blob: b5507a634953610dee1e6b4ebe8dd6cbfc677678 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXComment.h"
19#include "CXCursor.h"
20#include "CXSourceLocation.h"
21#include "CXString.h"
22#include "CXTranslationUnit.h"
23#include "CXType.h"
24#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000025#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000030#include "clang/Basic/Version.h"
31#include "clang/Frontend/ASTUnit.h"
32#include "clang/Frontend/CompilerInstance.h"
33#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000034#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000035#include "clang/Lex/HeaderSearch.h"
36#include "clang/Lex/Lexer.h"
37#include "clang/Lex/PreprocessingRecord.h"
38#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000039#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000040#include "llvm/ADT/Optional.h"
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/StringSwitch.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000043#include "llvm/Config/config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000044#include "llvm/Support/Compiler.h"
45#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000046#include "llvm/Support/Format.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/MemoryBuffer.h"
48#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000049#include "llvm/Support/Program.h"
50#include "llvm/Support/SaveAndRestore.h"
51#include "llvm/Support/Signals.h"
52#include "llvm/Support/Threading.h"
53#include "llvm/Support/Timer.h"
54#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000055
56#if HAVE_PTHREAD_H
57#include <pthread.h>
58#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000059
60using namespace clang;
61using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000062using namespace clang::cxtu;
63using namespace clang::cxindex;
64
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000065CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
66 if (!AU)
Guy Benyei11169dd2012-12-18 14:30:41 +000067 return 0;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000068 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000069 CXTranslationUnit D = new CXTranslationUnitImpl();
70 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000071 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000072 D->StringPool = new cxstring::CXStringPool();
Guy Benyei11169dd2012-12-18 14:30:41 +000073 D->Diagnostics = 0;
74 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Dmitri Gribenko9e605112013-11-13 22:16:51 +000075 D->CommentToXML = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +000076 return D;
77}
78
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000079bool cxtu::isASTReadError(ASTUnit *AU) {
80 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
81 DEnd = AU->stored_diag_end();
82 D != DEnd; ++D) {
83 if (D->getLevel() >= DiagnosticsEngine::Error &&
84 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
85 diag::DiagCat_AST_Deserialization_Issue)
86 return true;
87 }
88 return false;
89}
90
Guy Benyei11169dd2012-12-18 14:30:41 +000091cxtu::CXTUOwner::~CXTUOwner() {
92 if (TU)
93 clang_disposeTranslationUnit(TU);
94}
95
96/// \brief Compare two source ranges to determine their relative position in
97/// the translation unit.
98static RangeComparisonResult RangeCompare(SourceManager &SM,
99 SourceRange R1,
100 SourceRange R2) {
101 assert(R1.isValid() && "First range is invalid?");
102 assert(R2.isValid() && "Second range is invalid?");
103 if (R1.getEnd() != R2.getBegin() &&
104 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
105 return RangeBefore;
106 if (R2.getEnd() != R1.getBegin() &&
107 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
108 return RangeAfter;
109 return RangeOverlap;
110}
111
112/// \brief Determine if a source location falls within, before, or after a
113/// a given source range.
114static RangeComparisonResult LocationCompare(SourceManager &SM,
115 SourceLocation L, SourceRange R) {
116 assert(R.isValid() && "First range is invalid?");
117 assert(L.isValid() && "Second range is invalid?");
118 if (L == R.getBegin() || L == R.getEnd())
119 return RangeOverlap;
120 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
121 return RangeBefore;
122 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
123 return RangeAfter;
124 return RangeOverlap;
125}
126
127/// \brief Translate a Clang source range into a CIndex source range.
128///
129/// Clang internally represents ranges where the end location points to the
130/// start of the token at the end. However, for external clients it is more
131/// useful to have a CXSourceRange be a proper half-open interval. This routine
132/// does the appropriate translation.
133CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
134 const LangOptions &LangOpts,
135 const CharSourceRange &R) {
136 // We want the last character in this location, so we will adjust the
137 // location accordingly.
138 SourceLocation EndLoc = R.getEnd();
139 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
140 EndLoc = SM.getExpansionRange(EndLoc).second;
141 if (R.isTokenRange() && !EndLoc.isInvalid()) {
142 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
143 SM, LangOpts);
144 EndLoc = EndLoc.getLocWithOffset(Length);
145 }
146
Bill Wendlingeade3622013-01-23 08:25:41 +0000147 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000148 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000149 R.getBegin().getRawEncoding(),
150 EndLoc.getRawEncoding()
151 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000152 return Result;
153}
154
155//===----------------------------------------------------------------------===//
156// Cursor visitor.
157//===----------------------------------------------------------------------===//
158
159static SourceRange getRawCursorExtent(CXCursor C);
160static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
161
162
163RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
164 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
165}
166
167/// \brief Visit the given cursor and, if requested by the visitor,
168/// its children.
169///
170/// \param Cursor the cursor to visit.
171///
172/// \param CheckedRegionOfInterest if true, then the caller already checked
173/// that this cursor is within the region of interest.
174///
175/// \returns true if the visitation should be aborted, false if it
176/// should continue.
177bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
178 if (clang_isInvalid(Cursor.kind))
179 return false;
180
181 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000182 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000183 if (!D) {
184 assert(0 && "Invalid declaration cursor");
185 return true; // abort.
186 }
187
188 // Ignore implicit declarations, unless it's an objc method because
189 // currently we should report implicit methods for properties when indexing.
190 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
191 return false;
192 }
193
194 // If we have a range of interest, and this cursor doesn't intersect with it,
195 // we're done.
196 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
197 SourceRange Range = getRawCursorExtent(Cursor);
198 if (Range.isInvalid() || CompareRegionOfInterest(Range))
199 return false;
200 }
201
202 switch (Visitor(Cursor, Parent, ClientData)) {
203 case CXChildVisit_Break:
204 return true;
205
206 case CXChildVisit_Continue:
207 return false;
208
209 case CXChildVisit_Recurse: {
210 bool ret = VisitChildren(Cursor);
211 if (PostChildrenVisitor)
212 if (PostChildrenVisitor(Cursor, ClientData))
213 return true;
214 return ret;
215 }
216 }
217
218 llvm_unreachable("Invalid CXChildVisitResult!");
219}
220
221static bool visitPreprocessedEntitiesInRange(SourceRange R,
222 PreprocessingRecord &PPRec,
223 CursorVisitor &Visitor) {
224 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
225 FileID FID;
226
227 if (!Visitor.shouldVisitIncludedEntities()) {
228 // If the begin/end of the range lie in the same FileID, do the optimization
229 // where we skip preprocessed entities that do not come from the same FileID.
230 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
231 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
232 FID = FileID();
233 }
234
235 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
236 Entities = PPRec.getPreprocessedEntitiesInRange(R);
237 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
238 PPRec, FID);
239}
240
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000241bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000242 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000243 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000244
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000245 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 SourceManager &SM = Unit->getSourceManager();
247
248 std::pair<FileID, unsigned>
249 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
250 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
251
252 if (End.first != Begin.first) {
253 // If the end does not reside in the same file, try to recover by
254 // picking the end of the file of begin location.
255 End.first = Begin.first;
256 End.second = SM.getFileIDSize(Begin.first);
257 }
258
259 assert(Begin.first == End.first);
260 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000261 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000262
263 FileID File = Begin.first;
264 unsigned Offset = Begin.second;
265 unsigned Length = End.second - Begin.second;
266
267 if (!VisitDeclsOnly && !VisitPreprocessorLast)
268 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000271 if (visitDeclsFromFileRegion(File, Offset, Length))
272 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000273
274 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000275 return visitPreprocessedEntitiesInRegion();
276
277 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000278}
279
280static bool isInLexicalContext(Decl *D, DeclContext *DC) {
281 if (!DC)
282 return false;
283
284 for (DeclContext *DeclDC = D->getLexicalDeclContext();
285 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
286 if (DeclDC == DC)
287 return true;
288 }
289 return false;
290}
291
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000292bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000293 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000294 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000295 SourceManager &SM = Unit->getSourceManager();
296 SourceRange Range = RegionOfInterest;
297
298 SmallVector<Decl *, 16> Decls;
299 Unit->findFileRegionDecls(File, Offset, Length, Decls);
300
301 // If we didn't find any file level decls for the file, try looking at the
302 // file that it was included from.
303 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
304 bool Invalid = false;
305 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
306 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000307 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000308
309 SourceLocation Outer;
310 if (SLEntry.isFile())
311 Outer = SLEntry.getFile().getIncludeLoc();
312 else
313 Outer = SLEntry.getExpansion().getExpansionLocStart();
314 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000317 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000318 Length = 0;
319 Unit->findFileRegionDecls(File, Offset, Length, Decls);
320 }
321
322 assert(!Decls.empty());
323
324 bool VisitedAtLeastOnce = false;
325 DeclContext *CurDC = 0;
Craig Topper2341c0d2013-07-04 03:08:24 +0000326 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
327 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000328 Decl *D = *DIt;
329 if (D->getSourceRange().isInvalid())
330 continue;
331
332 if (isInLexicalContext(D, CurDC))
333 continue;
334
335 CurDC = dyn_cast<DeclContext>(D);
336
337 if (TagDecl *TD = dyn_cast<TagDecl>(D))
338 if (!TD->isFreeStanding())
339 continue;
340
341 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
342 if (CompRes == RangeBefore)
343 continue;
344 if (CompRes == RangeAfter)
345 break;
346
347 assert(CompRes == RangeOverlap);
348 VisitedAtLeastOnce = true;
349
350 if (isa<ObjCContainerDecl>(D)) {
351 FileDI_current = &DIt;
352 FileDE_current = DE;
353 } else {
354 FileDI_current = 0;
355 }
356
357 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000358 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000359 }
360
361 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000362 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363
364 // No Decls overlapped with the range. Move up the lexical context until there
365 // is a context that contains the range or we reach the translation unit
366 // level.
367 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
368 : (*(DIt-1))->getLexicalDeclContext();
369
370 while (DC && !DC->isTranslationUnit()) {
371 Decl *D = cast<Decl>(DC);
372 SourceRange CurDeclRange = D->getSourceRange();
373 if (CurDeclRange.isInvalid())
374 break;
375
376 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000377 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
378 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000379 }
380
381 DC = D->getLexicalDeclContext();
382 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000383
384 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000385}
386
387bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
388 if (!AU->getPreprocessor().getPreprocessingRecord())
389 return false;
390
391 PreprocessingRecord &PPRec
392 = *AU->getPreprocessor().getPreprocessingRecord();
393 SourceManager &SM = AU->getSourceManager();
394
395 if (RegionOfInterest.isValid()) {
396 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
397 SourceLocation B = MappedRange.getBegin();
398 SourceLocation E = MappedRange.getEnd();
399
400 if (AU->isInPreambleFileID(B)) {
401 if (SM.isLoadedSourceLocation(E))
402 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
403 PPRec, *this);
404
405 // Beginning of range lies in the preamble but it also extends beyond
406 // it into the main file. Split the range into 2 parts, one covering
407 // the preamble and another covering the main file. This allows subsequent
408 // calls to visitPreprocessedEntitiesInRange to accept a source range that
409 // lies in the same FileID, allowing it to skip preprocessed entities that
410 // do not come from the same FileID.
411 bool breaked =
412 visitPreprocessedEntitiesInRange(
413 SourceRange(B, AU->getEndOfPreambleFileID()),
414 PPRec, *this);
415 if (breaked) return true;
416 return visitPreprocessedEntitiesInRange(
417 SourceRange(AU->getStartOfMainFileID(), E),
418 PPRec, *this);
419 }
420
421 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
422 }
423
424 bool OnlyLocalDecls
425 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
426
427 if (OnlyLocalDecls)
428 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
429 PPRec);
430
431 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
432}
433
434template<typename InputIterator>
435bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
436 InputIterator Last,
437 PreprocessingRecord &PPRec,
438 FileID FID) {
439 for (; First != Last; ++First) {
440 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
441 continue;
442
443 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000444 if (!PPE)
445 continue;
446
Guy Benyei11169dd2012-12-18 14:30:41 +0000447 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
448 if (Visit(MakeMacroExpansionCursor(ME, TU)))
449 return true;
450
451 continue;
452 }
453
454 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
455 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
456 return true;
457
458 continue;
459 }
460
461 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
462 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
463 return true;
464
465 continue;
466 }
467 }
468
469 return false;
470}
471
472/// \brief Visit the children of the given cursor.
473///
474/// \returns true if the visitation should be aborted, false if it
475/// should continue.
476bool CursorVisitor::VisitChildren(CXCursor Cursor) {
477 if (clang_isReference(Cursor.kind) &&
478 Cursor.kind != CXCursor_CXXBaseSpecifier) {
479 // By definition, references have no children.
480 return false;
481 }
482
483 // Set the Parent field to Cursor, then back to its old value once we're
484 // done.
485 SetParentRAII SetParent(Parent, StmtParent, Cursor);
486
487 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000488 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000489 if (!D)
490 return false;
491
492 return VisitAttributes(D) || Visit(D);
493 }
494
495 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000496 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 return Visit(S);
498
499 return false;
500 }
501
502 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000503 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000504 return Visit(E);
505
506 return false;
507 }
508
509 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000510 CXTranslationUnit TU = getCursorTU(Cursor);
511 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000512
513 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
514 for (unsigned I = 0; I != 2; ++I) {
515 if (VisitOrder[I]) {
516 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
517 RegionOfInterest.isInvalid()) {
518 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
519 TLEnd = CXXUnit->top_level_end();
520 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000521 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000522 return true;
523 }
524 } else if (VisitDeclContext(
525 CXXUnit->getASTContext().getTranslationUnitDecl()))
526 return true;
527 continue;
528 }
529
530 // Walk the preprocessing record.
531 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
532 visitPreprocessedEntitiesInRegion();
533 }
534
535 return false;
536 }
537
538 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000539 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000540 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
541 return Visit(BaseTSInfo->getTypeLoc());
542 }
543 }
544 }
545
546 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000547 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000549 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000550 return Visit(cxcursor::MakeCursorObjCClassRef(
551 ObjT->getInterface(),
552 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000553 }
554
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000555 // If pointing inside a macro definition, check if the token is an identifier
556 // that was ever defined as a macro. In such a case, create a "pseudo" macro
557 // expansion cursor for that token.
558 SourceLocation BeginLoc = RegionOfInterest.getBegin();
559 if (Cursor.kind == CXCursor_MacroDefinition &&
560 BeginLoc == RegionOfInterest.getEnd()) {
561 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000562 const MacroInfo *MI =
563 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000564 if (MacroDefinition *MacroDef =
565 checkForMacroInMacroDefinition(MI, Loc, TU))
566 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
567 }
568
Guy Benyei11169dd2012-12-18 14:30:41 +0000569 // Nothing to visit at the moment.
570 return false;
571}
572
573bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
574 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
575 if (Visit(TSInfo->getTypeLoc()))
576 return true;
577
578 if (Stmt *Body = B->getBody())
579 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
580
581 return false;
582}
583
Ted Kremenek03325582013-02-21 01:29:01 +0000584Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000585 if (RegionOfInterest.isValid()) {
586 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
587 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000588 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000589
590 switch (CompareRegionOfInterest(Range)) {
591 case RangeBefore:
592 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000593 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000594
595 case RangeAfter:
596 // This declaration comes after the region of interest; we're done.
597 return false;
598
599 case RangeOverlap:
600 // This declaration overlaps the region of interest; visit it.
601 break;
602 }
603 }
604 return true;
605}
606
607bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
608 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
609
610 // FIXME: Eventually remove. This part of a hack to support proper
611 // iteration over all Decls contained lexically within an ObjC container.
612 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
613 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
614
615 for ( ; I != E; ++I) {
616 Decl *D = *I;
617 if (D->getLexicalDeclContext() != DC)
618 continue;
619 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
620
621 // Ignore synthesized ivars here, otherwise if we have something like:
622 // @synthesize prop = _prop;
623 // and '_prop' is not declared, we will encounter a '_prop' ivar before
624 // encountering the 'prop' synthesize declaration and we will think that
625 // we passed the region-of-interest.
626 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
627 if (ivarD->getSynthesize())
628 continue;
629 }
630
631 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
632 // declarations is a mismatch with the compiler semantics.
633 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
634 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
635 if (!ID->isThisDeclarationADefinition())
636 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
637
638 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
639 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
640 if (!PD->isThisDeclarationADefinition())
641 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
642 }
643
Ted Kremenek03325582013-02-21 01:29:01 +0000644 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000645 if (!V.hasValue())
646 continue;
647 if (!V.getValue())
648 return false;
649 if (Visit(Cursor, true))
650 return true;
651 }
652 return false;
653}
654
655bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
656 llvm_unreachable("Translation units are visited directly by Visit()");
657}
658
659bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
660 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
661 return Visit(TSInfo->getTypeLoc());
662
663 return false;
664}
665
666bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
667 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
668 return Visit(TSInfo->getTypeLoc());
669
670 return false;
671}
672
673bool CursorVisitor::VisitTagDecl(TagDecl *D) {
674 return VisitDeclContext(D);
675}
676
677bool CursorVisitor::VisitClassTemplateSpecializationDecl(
678 ClassTemplateSpecializationDecl *D) {
679 bool ShouldVisitBody = false;
680 switch (D->getSpecializationKind()) {
681 case TSK_Undeclared:
682 case TSK_ImplicitInstantiation:
683 // Nothing to visit
684 return false;
685
686 case TSK_ExplicitInstantiationDeclaration:
687 case TSK_ExplicitInstantiationDefinition:
688 break;
689
690 case TSK_ExplicitSpecialization:
691 ShouldVisitBody = true;
692 break;
693 }
694
695 // Visit the template arguments used in the specialization.
696 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
697 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000698 if (TemplateSpecializationTypeLoc TSTLoc =
699 TL.getAs<TemplateSpecializationTypeLoc>()) {
700 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
701 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000702 return true;
703 }
704 }
705
706 if (ShouldVisitBody && VisitCXXRecordDecl(D))
707 return true;
708
709 return false;
710}
711
712bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
713 ClassTemplatePartialSpecializationDecl *D) {
714 // FIXME: Visit the "outer" template parameter lists on the TagDecl
715 // before visiting these template parameters.
716 if (VisitTemplateParameters(D->getTemplateParameters()))
717 return true;
718
719 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000720 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
721 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
722 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000723 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
724 return true;
725
726 return VisitCXXRecordDecl(D);
727}
728
729bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
730 // Visit the default argument.
731 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
732 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
733 if (Visit(DefArg->getTypeLoc()))
734 return true;
735
736 return false;
737}
738
739bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
740 if (Expr *Init = D->getInitExpr())
741 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
742 return false;
743}
744
745bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000746 unsigned NumParamList = DD->getNumTemplateParameterLists();
747 for (unsigned i = 0; i < NumParamList; i++) {
748 TemplateParameterList* Params = DD->getTemplateParameterList(i);
749 if (VisitTemplateParameters(Params))
750 return true;
751 }
752
Guy Benyei11169dd2012-12-18 14:30:41 +0000753 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
754 if (Visit(TSInfo->getTypeLoc()))
755 return true;
756
757 // Visit the nested-name-specifier, if present.
758 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
759 if (VisitNestedNameSpecifierLoc(QualifierLoc))
760 return true;
761
762 return false;
763}
764
765/// \brief Compare two base or member initializers based on their source order.
Benjamin Kramer04bf1872013-09-22 14:10:29 +0000766static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
767 CXXCtorInitializer *const *Y) {
768 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
Guy Benyei11169dd2012-12-18 14:30:41 +0000769}
770
771bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000772 unsigned NumParamList = ND->getNumTemplateParameterLists();
773 for (unsigned i = 0; i < NumParamList; i++) {
774 TemplateParameterList* Params = ND->getTemplateParameterList(i);
775 if (VisitTemplateParameters(Params))
776 return true;
777 }
778
Guy Benyei11169dd2012-12-18 14:30:41 +0000779 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
780 // Visit the function declaration's syntactic components in the order
781 // written. This requires a bit of work.
782 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000783 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000784
785 // If we have a function declared directly (without the use of a typedef),
786 // visit just the return type. Otherwise, just visit the function's type
787 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000788 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000789 (!FTL && Visit(TL)))
790 return true;
791
792 // Visit the nested-name-specifier, if present.
793 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
794 if (VisitNestedNameSpecifierLoc(QualifierLoc))
795 return true;
796
797 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000798 if (!isa<CXXDestructorDecl>(ND))
799 if (VisitDeclarationNameInfo(ND->getNameInfo()))
800 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000801
802 // FIXME: Visit explicitly-specified template arguments!
803
804 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000805 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000806 return true;
807
Bill Wendling44426052012-12-20 19:22:21 +0000808 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000809 }
810
811 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
812 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
813 // Find the initializers that were written in the source.
814 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
815 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
816 IEnd = Constructor->init_end();
817 I != IEnd; ++I) {
818 if (!(*I)->isWritten())
819 continue;
820
821 WrittenInits.push_back(*I);
822 }
823
824 // Sort the initializers in source order
825 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
826 &CompareCXXCtorInitializers);
827
828 // Visit the initializers in source order
829 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
830 CXXCtorInitializer *Init = WrittenInits[I];
831 if (Init->isAnyMemberInitializer()) {
832 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
833 Init->getMemberLocation(), TU)))
834 return true;
835 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
836 if (Visit(TInfo->getTypeLoc()))
837 return true;
838 }
839
840 // Visit the initializer value.
841 if (Expr *Initializer = Init->getInit())
842 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
843 return true;
844 }
845 }
846
847 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
848 return true;
849 }
850
851 return false;
852}
853
854bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
855 if (VisitDeclaratorDecl(D))
856 return true;
857
858 if (Expr *BitWidth = D->getBitWidth())
859 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
860
861 return false;
862}
863
864bool CursorVisitor::VisitVarDecl(VarDecl *D) {
865 if (VisitDeclaratorDecl(D))
866 return true;
867
868 if (Expr *Init = D->getInit())
869 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
870
871 return false;
872}
873
874bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
875 if (VisitDeclaratorDecl(D))
876 return true;
877
878 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
879 if (Expr *DefArg = D->getDefaultArgument())
880 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
881
882 return false;
883}
884
885bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
886 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
887 // before visiting these template parameters.
888 if (VisitTemplateParameters(D->getTemplateParameters()))
889 return true;
890
891 return VisitFunctionDecl(D->getTemplatedDecl());
892}
893
894bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
895 // FIXME: Visit the "outer" template parameter lists on the TagDecl
896 // before visiting these template parameters.
897 if (VisitTemplateParameters(D->getTemplateParameters()))
898 return true;
899
900 return VisitCXXRecordDecl(D->getTemplatedDecl());
901}
902
903bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
904 if (VisitTemplateParameters(D->getTemplateParameters()))
905 return true;
906
907 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
908 VisitTemplateArgumentLoc(D->getDefaultArgument()))
909 return true;
910
911 return false;
912}
913
914bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000915 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000916 if (Visit(TSInfo->getTypeLoc()))
917 return true;
918
919 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
920 PEnd = ND->param_end();
921 P != PEnd; ++P) {
922 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
923 return true;
924 }
925
926 if (ND->isThisDeclarationADefinition() &&
927 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
928 return true;
929
930 return false;
931}
932
933template <typename DeclIt>
934static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
935 SourceManager &SM, SourceLocation EndLoc,
936 SmallVectorImpl<Decl *> &Decls) {
937 DeclIt next = *DI_current;
938 while (++next != DE_current) {
939 Decl *D_next = *next;
940 if (!D_next)
941 break;
942 SourceLocation L = D_next->getLocStart();
943 if (!L.isValid())
944 break;
945 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
946 *DI_current = next;
947 Decls.push_back(D_next);
948 continue;
949 }
950 break;
951 }
952}
953
Guy Benyei11169dd2012-12-18 14:30:41 +0000954bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
955 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
956 // an @implementation can lexically contain Decls that are not properly
957 // nested in the AST. When we identify such cases, we need to retrofit
958 // this nesting here.
959 if (!DI_current && !FileDI_current)
960 return VisitDeclContext(D);
961
962 // Scan the Decls that immediately come after the container
963 // in the current DeclContext. If any fall within the
964 // container's lexical region, stash them into a vector
965 // for later processing.
966 SmallVector<Decl *, 24> DeclsInContainer;
967 SourceLocation EndLoc = D->getSourceRange().getEnd();
968 SourceManager &SM = AU->getSourceManager();
969 if (EndLoc.isValid()) {
970 if (DI_current) {
971 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
972 DeclsInContainer);
973 } else {
974 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
975 DeclsInContainer);
976 }
977 }
978
979 // The common case.
980 if (DeclsInContainer.empty())
981 return VisitDeclContext(D);
982
983 // Get all the Decls in the DeclContext, and sort them with the
984 // additional ones we've collected. Then visit them.
985 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
986 I!=E; ++I) {
987 Decl *subDecl = *I;
988 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
989 subDecl->getLocStart().isInvalid())
990 continue;
991 DeclsInContainer.push_back(subDecl);
992 }
993
994 // Now sort the Decls so that they appear in lexical order.
995 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000996 [&SM](Decl *A, Decl *B) {
997 SourceLocation L_A = A->getLocStart();
998 SourceLocation L_B = B->getLocStart();
999 assert(L_A.isValid() && L_B.isValid());
1000 return SM.isBeforeInTranslationUnit(L_A, L_B);
1001 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001002
1003 // Now visit the decls.
1004 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1005 E = DeclsInContainer.end(); I != E; ++I) {
1006 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001007 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001008 if (!V.hasValue())
1009 continue;
1010 if (!V.getValue())
1011 return false;
1012 if (Visit(Cursor, true))
1013 return true;
1014 }
1015 return false;
1016}
1017
1018bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1019 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1020 TU)))
1021 return true;
1022
1023 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1024 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1025 E = ND->protocol_end(); I != E; ++I, ++PL)
1026 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1027 return true;
1028
1029 return VisitObjCContainerDecl(ND);
1030}
1031
1032bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1033 if (!PID->isThisDeclarationADefinition())
1034 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1035
1036 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1037 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1038 E = PID->protocol_end(); I != E; ++I, ++PL)
1039 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1040 return true;
1041
1042 return VisitObjCContainerDecl(PID);
1043}
1044
1045bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1046 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1047 return true;
1048
1049 // FIXME: This implements a workaround with @property declarations also being
1050 // installed in the DeclContext for the @interface. Eventually this code
1051 // should be removed.
1052 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1053 if (!CDecl || !CDecl->IsClassExtension())
1054 return false;
1055
1056 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1057 if (!ID)
1058 return false;
1059
1060 IdentifierInfo *PropertyId = PD->getIdentifier();
1061 ObjCPropertyDecl *prevDecl =
1062 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1063
1064 if (!prevDecl)
1065 return false;
1066
1067 // Visit synthesized methods since they will be skipped when visiting
1068 // the @interface.
1069 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1070 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1071 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1072 return true;
1073
1074 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1075 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1076 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1077 return true;
1078
1079 return false;
1080}
1081
1082bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1083 if (!D->isThisDeclarationADefinition()) {
1084 // Forward declaration is treated like a reference.
1085 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1086 }
1087
1088 // Issue callbacks for super class.
1089 if (D->getSuperClass() &&
1090 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1091 D->getSuperClassLoc(),
1092 TU)))
1093 return true;
1094
1095 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1096 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1097 E = D->protocol_end(); I != E; ++I, ++PL)
1098 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1099 return true;
1100
1101 return VisitObjCContainerDecl(D);
1102}
1103
1104bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1105 return VisitObjCContainerDecl(D);
1106}
1107
1108bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1109 // 'ID' could be null when dealing with invalid code.
1110 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1111 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1112 return true;
1113
1114 return VisitObjCImplDecl(D);
1115}
1116
1117bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1118#if 0
1119 // Issue callbacks for super class.
1120 // FIXME: No source location information!
1121 if (D->getSuperClass() &&
1122 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1123 D->getSuperClassLoc(),
1124 TU)))
1125 return true;
1126#endif
1127
1128 return VisitObjCImplDecl(D);
1129}
1130
1131bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1132 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1133 if (PD->isIvarNameSpecified())
1134 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1135
1136 return false;
1137}
1138
1139bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1140 return VisitDeclContext(D);
1141}
1142
1143bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1144 // Visit nested-name-specifier.
1145 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1146 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1147 return true;
1148
1149 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1150 D->getTargetNameLoc(), TU));
1151}
1152
1153bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1154 // Visit nested-name-specifier.
1155 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1156 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1157 return true;
1158 }
1159
1160 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1161 return true;
1162
1163 return VisitDeclarationNameInfo(D->getNameInfo());
1164}
1165
1166bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1167 // Visit nested-name-specifier.
1168 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1169 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1170 return true;
1171
1172 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1173 D->getIdentLocation(), TU));
1174}
1175
1176bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1177 // Visit nested-name-specifier.
1178 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1179 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1180 return true;
1181 }
1182
1183 return VisitDeclarationNameInfo(D->getNameInfo());
1184}
1185
1186bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1187 UnresolvedUsingTypenameDecl *D) {
1188 // Visit nested-name-specifier.
1189 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1190 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1191 return true;
1192
1193 return false;
1194}
1195
1196bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1197 switch (Name.getName().getNameKind()) {
1198 case clang::DeclarationName::Identifier:
1199 case clang::DeclarationName::CXXLiteralOperatorName:
1200 case clang::DeclarationName::CXXOperatorName:
1201 case clang::DeclarationName::CXXUsingDirective:
1202 return false;
1203
1204 case clang::DeclarationName::CXXConstructorName:
1205 case clang::DeclarationName::CXXDestructorName:
1206 case clang::DeclarationName::CXXConversionFunctionName:
1207 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1208 return Visit(TSInfo->getTypeLoc());
1209 return false;
1210
1211 case clang::DeclarationName::ObjCZeroArgSelector:
1212 case clang::DeclarationName::ObjCOneArgSelector:
1213 case clang::DeclarationName::ObjCMultiArgSelector:
1214 // FIXME: Per-identifier location info?
1215 return false;
1216 }
1217
1218 llvm_unreachable("Invalid DeclarationName::Kind!");
1219}
1220
1221bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1222 SourceRange Range) {
1223 // FIXME: This whole routine is a hack to work around the lack of proper
1224 // source information in nested-name-specifiers (PR5791). Since we do have
1225 // a beginning source location, we can visit the first component of the
1226 // nested-name-specifier, if it's a single-token component.
1227 if (!NNS)
1228 return false;
1229
1230 // Get the first component in the nested-name-specifier.
1231 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1232 NNS = Prefix;
1233
1234 switch (NNS->getKind()) {
1235 case NestedNameSpecifier::Namespace:
1236 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1237 TU));
1238
1239 case NestedNameSpecifier::NamespaceAlias:
1240 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1241 Range.getBegin(), TU));
1242
1243 case NestedNameSpecifier::TypeSpec: {
1244 // If the type has a form where we know that the beginning of the source
1245 // range matches up with a reference cursor. Visit the appropriate reference
1246 // cursor.
1247 const Type *T = NNS->getAsType();
1248 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1249 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1250 if (const TagType *Tag = dyn_cast<TagType>(T))
1251 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1252 if (const TemplateSpecializationType *TST
1253 = dyn_cast<TemplateSpecializationType>(T))
1254 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1255 break;
1256 }
1257
1258 case NestedNameSpecifier::TypeSpecWithTemplate:
1259 case NestedNameSpecifier::Global:
1260 case NestedNameSpecifier::Identifier:
1261 break;
1262 }
1263
1264 return false;
1265}
1266
1267bool
1268CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1269 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1270 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1271 Qualifiers.push_back(Qualifier);
1272
1273 while (!Qualifiers.empty()) {
1274 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1275 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1276 switch (NNS->getKind()) {
1277 case NestedNameSpecifier::Namespace:
1278 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1279 Q.getLocalBeginLoc(),
1280 TU)))
1281 return true;
1282
1283 break;
1284
1285 case NestedNameSpecifier::NamespaceAlias:
1286 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1287 Q.getLocalBeginLoc(),
1288 TU)))
1289 return true;
1290
1291 break;
1292
1293 case NestedNameSpecifier::TypeSpec:
1294 case NestedNameSpecifier::TypeSpecWithTemplate:
1295 if (Visit(Q.getTypeLoc()))
1296 return true;
1297
1298 break;
1299
1300 case NestedNameSpecifier::Global:
1301 case NestedNameSpecifier::Identifier:
1302 break;
1303 }
1304 }
1305
1306 return false;
1307}
1308
1309bool CursorVisitor::VisitTemplateParameters(
1310 const TemplateParameterList *Params) {
1311 if (!Params)
1312 return false;
1313
1314 for (TemplateParameterList::const_iterator P = Params->begin(),
1315 PEnd = Params->end();
1316 P != PEnd; ++P) {
1317 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1318 return true;
1319 }
1320
1321 return false;
1322}
1323
1324bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1325 switch (Name.getKind()) {
1326 case TemplateName::Template:
1327 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1328
1329 case TemplateName::OverloadedTemplate:
1330 // Visit the overloaded template set.
1331 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1332 return true;
1333
1334 return false;
1335
1336 case TemplateName::DependentTemplate:
1337 // FIXME: Visit nested-name-specifier.
1338 return false;
1339
1340 case TemplateName::QualifiedTemplate:
1341 // FIXME: Visit nested-name-specifier.
1342 return Visit(MakeCursorTemplateRef(
1343 Name.getAsQualifiedTemplateName()->getDecl(),
1344 Loc, TU));
1345
1346 case TemplateName::SubstTemplateTemplateParm:
1347 return Visit(MakeCursorTemplateRef(
1348 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1349 Loc, TU));
1350
1351 case TemplateName::SubstTemplateTemplateParmPack:
1352 return Visit(MakeCursorTemplateRef(
1353 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1354 Loc, TU));
1355 }
1356
1357 llvm_unreachable("Invalid TemplateName::Kind!");
1358}
1359
1360bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1361 switch (TAL.getArgument().getKind()) {
1362 case TemplateArgument::Null:
1363 case TemplateArgument::Integral:
1364 case TemplateArgument::Pack:
1365 return false;
1366
1367 case TemplateArgument::Type:
1368 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1369 return Visit(TSInfo->getTypeLoc());
1370 return false;
1371
1372 case TemplateArgument::Declaration:
1373 if (Expr *E = TAL.getSourceDeclExpression())
1374 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1375 return false;
1376
1377 case TemplateArgument::NullPtr:
1378 if (Expr *E = TAL.getSourceNullPtrExpression())
1379 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1380 return false;
1381
1382 case TemplateArgument::Expression:
1383 if (Expr *E = TAL.getSourceExpression())
1384 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1385 return false;
1386
1387 case TemplateArgument::Template:
1388 case TemplateArgument::TemplateExpansion:
1389 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1390 return true;
1391
1392 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1393 TAL.getTemplateNameLoc());
1394 }
1395
1396 llvm_unreachable("Invalid TemplateArgument::Kind!");
1397}
1398
1399bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1400 return VisitDeclContext(D);
1401}
1402
1403bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1404 return Visit(TL.getUnqualifiedLoc());
1405}
1406
1407bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1408 ASTContext &Context = AU->getASTContext();
1409
1410 // Some builtin types (such as Objective-C's "id", "sel", and
1411 // "Class") have associated declarations. Create cursors for those.
1412 QualType VisitType;
1413 switch (TL.getTypePtr()->getKind()) {
1414
1415 case BuiltinType::Void:
1416 case BuiltinType::NullPtr:
1417 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001418 case BuiltinType::OCLImage1d:
1419 case BuiltinType::OCLImage1dArray:
1420 case BuiltinType::OCLImage1dBuffer:
1421 case BuiltinType::OCLImage2d:
1422 case BuiltinType::OCLImage2dArray:
1423 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001424 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001425 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001426#define BUILTIN_TYPE(Id, SingletonId)
1427#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1428#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1429#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1430#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1431#include "clang/AST/BuiltinTypes.def"
1432 break;
1433
1434 case BuiltinType::ObjCId:
1435 VisitType = Context.getObjCIdType();
1436 break;
1437
1438 case BuiltinType::ObjCClass:
1439 VisitType = Context.getObjCClassType();
1440 break;
1441
1442 case BuiltinType::ObjCSel:
1443 VisitType = Context.getObjCSelType();
1444 break;
1445 }
1446
1447 if (!VisitType.isNull()) {
1448 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1449 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1450 TU));
1451 }
1452
1453 return false;
1454}
1455
1456bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1457 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1458}
1459
1460bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1461 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1462}
1463
1464bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1465 if (TL.isDefinition())
1466 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1467
1468 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1469}
1470
1471bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1472 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1473}
1474
1475bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1476 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1477 return true;
1478
1479 return false;
1480}
1481
1482bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1483 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1484 return true;
1485
1486 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1487 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1488 TU)))
1489 return true;
1490 }
1491
1492 return false;
1493}
1494
1495bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1496 return Visit(TL.getPointeeLoc());
1497}
1498
1499bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1500 return Visit(TL.getInnerLoc());
1501}
1502
1503bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1504 return Visit(TL.getPointeeLoc());
1505}
1506
1507bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1508 return Visit(TL.getPointeeLoc());
1509}
1510
1511bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1512 return Visit(TL.getPointeeLoc());
1513}
1514
1515bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1516 return Visit(TL.getPointeeLoc());
1517}
1518
1519bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1520 return Visit(TL.getPointeeLoc());
1521}
1522
1523bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1524 return Visit(TL.getModifiedLoc());
1525}
1526
1527bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1528 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001529 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001530 return true;
1531
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001532 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1533 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001534 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1535 return true;
1536
1537 return false;
1538}
1539
1540bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1541 if (Visit(TL.getElementLoc()))
1542 return true;
1543
1544 if (Expr *Size = TL.getSizeExpr())
1545 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1546
1547 return false;
1548}
1549
Reid Kleckner8a365022013-06-24 17:51:48 +00001550bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1551 return Visit(TL.getOriginalLoc());
1552}
1553
Reid Kleckner0503a872013-12-05 01:23:43 +00001554bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1555 return Visit(TL.getOriginalLoc());
1556}
1557
Guy Benyei11169dd2012-12-18 14:30:41 +00001558bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1559 TemplateSpecializationTypeLoc TL) {
1560 // Visit the template name.
1561 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1562 TL.getTemplateNameLoc()))
1563 return true;
1564
1565 // Visit the template arguments.
1566 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1567 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1568 return true;
1569
1570 return false;
1571}
1572
1573bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1574 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1575}
1576
1577bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1578 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1579 return Visit(TSInfo->getTypeLoc());
1580
1581 return false;
1582}
1583
1584bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1585 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1586 return Visit(TSInfo->getTypeLoc());
1587
1588 return false;
1589}
1590
1591bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1592 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1593 return true;
1594
1595 return false;
1596}
1597
1598bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1599 DependentTemplateSpecializationTypeLoc TL) {
1600 // Visit the nested-name-specifier, if there is one.
1601 if (TL.getQualifierLoc() &&
1602 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1603 return true;
1604
1605 // Visit the template arguments.
1606 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1607 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1608 return true;
1609
1610 return false;
1611}
1612
1613bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1614 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1615 return true;
1616
1617 return Visit(TL.getNamedTypeLoc());
1618}
1619
1620bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1621 return Visit(TL.getPatternLoc());
1622}
1623
1624bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1625 if (Expr *E = TL.getUnderlyingExpr())
1626 return Visit(MakeCXCursor(E, StmtParent, TU));
1627
1628 return false;
1629}
1630
1631bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1632 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1633}
1634
1635bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1636 return Visit(TL.getValueLoc());
1637}
1638
1639#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1640bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1641 return Visit##PARENT##Loc(TL); \
1642}
1643
1644DEFAULT_TYPELOC_IMPL(Complex, Type)
1645DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1646DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1647DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1648DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1649DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1650DEFAULT_TYPELOC_IMPL(Vector, Type)
1651DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1652DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1653DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1654DEFAULT_TYPELOC_IMPL(Record, TagType)
1655DEFAULT_TYPELOC_IMPL(Enum, TagType)
1656DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1657DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1658DEFAULT_TYPELOC_IMPL(Auto, Type)
1659
1660bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1661 // Visit the nested-name-specifier, if present.
1662 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1663 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1664 return true;
1665
1666 if (D->isCompleteDefinition()) {
1667 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1668 E = D->bases_end(); I != E; ++I) {
1669 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1670 return true;
1671 }
1672 }
1673
1674 return VisitTagDecl(D);
1675}
1676
1677bool CursorVisitor::VisitAttributes(Decl *D) {
1678 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1679 i != e; ++i)
1680 if (Visit(MakeCXCursor(*i, D, TU)))
1681 return true;
1682
1683 return false;
1684}
1685
1686//===----------------------------------------------------------------------===//
1687// Data-recursive visitor methods.
1688//===----------------------------------------------------------------------===//
1689
1690namespace {
1691#define DEF_JOB(NAME, DATA, KIND)\
1692class NAME : public VisitorJob {\
1693public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001694 NAME(const DATA *d, CXCursor parent) : \
1695 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001696 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001697 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001698};
1699
1700DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1701DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1702DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1703DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1704DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1705 ExplicitTemplateArgsVisitKind)
1706DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1707DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1708DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1709#undef DEF_JOB
1710
1711class DeclVisit : public VisitorJob {
1712public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001713 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001714 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001715 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001716 static bool classof(const VisitorJob *VJ) {
1717 return VJ->getKind() == DeclVisitKind;
1718 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001719 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001720 bool isFirst() const { return data[1] ? true : false; }
1721};
1722class TypeLocVisit : public VisitorJob {
1723public:
1724 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1725 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1726 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1727
1728 static bool classof(const VisitorJob *VJ) {
1729 return VJ->getKind() == TypeLocVisitKind;
1730 }
1731
1732 TypeLoc get() const {
1733 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001734 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001735 }
1736};
1737
1738class LabelRefVisit : public VisitorJob {
1739public:
1740 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1741 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1742 labelLoc.getPtrEncoding()) {}
1743
1744 static bool classof(const VisitorJob *VJ) {
1745 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1746 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001747 const LabelDecl *get() const {
1748 return static_cast<const LabelDecl *>(data[0]);
1749 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001750 SourceLocation getLoc() const {
1751 return SourceLocation::getFromPtrEncoding(data[1]); }
1752};
1753
1754class NestedNameSpecifierLocVisit : public VisitorJob {
1755public:
1756 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1757 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1758 Qualifier.getNestedNameSpecifier(),
1759 Qualifier.getOpaqueData()) { }
1760
1761 static bool classof(const VisitorJob *VJ) {
1762 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1763 }
1764
1765 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001766 return NestedNameSpecifierLoc(
1767 const_cast<NestedNameSpecifier *>(
1768 static_cast<const NestedNameSpecifier *>(data[0])),
1769 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001770 }
1771};
1772
1773class DeclarationNameInfoVisit : public VisitorJob {
1774public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001775 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001776 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001777 static bool classof(const VisitorJob *VJ) {
1778 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1779 }
1780 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001781 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001782 switch (S->getStmtClass()) {
1783 default:
1784 llvm_unreachable("Unhandled Stmt");
1785 case clang::Stmt::MSDependentExistsStmtClass:
1786 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1787 case Stmt::CXXDependentScopeMemberExprClass:
1788 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1789 case Stmt::DependentScopeDeclRefExprClass:
1790 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1791 }
1792 }
1793};
1794class MemberRefVisit : public VisitorJob {
1795public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001796 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001797 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1798 L.getPtrEncoding()) {}
1799 static bool classof(const VisitorJob *VJ) {
1800 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1801 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001802 const FieldDecl *get() const {
1803 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001804 }
1805 SourceLocation getLoc() const {
1806 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1807 }
1808};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001809class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001810 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001811 VisitorWorkList &WL;
1812 CXCursor Parent;
1813public:
1814 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1815 : WL(wl), Parent(parent) {}
1816
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001817 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1818 void VisitBlockExpr(const BlockExpr *B);
1819 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1820 void VisitCompoundStmt(const CompoundStmt *S);
1821 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1822 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1823 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1824 void VisitCXXNewExpr(const CXXNewExpr *E);
1825 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1826 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1827 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1828 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1829 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1830 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1831 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1832 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1833 void VisitDeclRefExpr(const DeclRefExpr *D);
1834 void VisitDeclStmt(const DeclStmt *S);
1835 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1836 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1837 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1838 void VisitForStmt(const ForStmt *FS);
1839 void VisitGotoStmt(const GotoStmt *GS);
1840 void VisitIfStmt(const IfStmt *If);
1841 void VisitInitListExpr(const InitListExpr *IE);
1842 void VisitMemberExpr(const MemberExpr *M);
1843 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1844 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1845 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1846 void VisitOverloadExpr(const OverloadExpr *E);
1847 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1848 void VisitStmt(const Stmt *S);
1849 void VisitSwitchStmt(const SwitchStmt *S);
1850 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001851 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1852 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1853 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1854 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1855 void VisitVAArgExpr(const VAArgExpr *E);
1856 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1857 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1858 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1859 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001860 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1861 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001862 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001863
Guy Benyei11169dd2012-12-18 14:30:41 +00001864private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001865 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001866 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1867 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001868 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1869 void AddStmt(const Stmt *S);
1870 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001871 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001872 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001873 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001874};
1875} // end anonyous namespace
1876
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001877void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001878 // 'S' should always be non-null, since it comes from the
1879 // statement we are visiting.
1880 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1881}
1882
1883void
1884EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1885 if (Qualifier)
1886 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1887}
1888
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001889void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001890 if (S)
1891 WL.push_back(StmtVisit(S, Parent));
1892}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001893void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001894 if (D)
1895 WL.push_back(DeclVisit(D, Parent, isFirst));
1896}
1897void EnqueueVisitor::
1898 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1899 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001900 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001901}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001903 if (D)
1904 WL.push_back(MemberRefVisit(D, L, Parent));
1905}
1906void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1907 if (TI)
1908 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1909 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001910void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001911 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001912 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001913 AddStmt(*Child);
1914 }
1915 if (size == WL.size())
1916 return;
1917 // Now reverse the entries we just added. This will match the DFS
1918 // ordering performed by the worklist.
1919 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1920 std::reverse(I, E);
1921}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001922namespace {
1923class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1924 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001925 /// \brief Process clauses with list of variables.
1926 template <typename T>
1927 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001928public:
1929 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1930#define OPENMP_CLAUSE(Name, Class) \
1931 void Visit##Class(const Class *C);
1932#include "clang/Basic/OpenMPKinds.def"
1933};
1934
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001935void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1936 Visitor->AddStmt(C->getCondition());
1937}
1938
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001939void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001940
1941template<typename T>
1942void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
1943 for (typename T::varlist_const_iterator I = Node->varlist_begin(),
1944 E = Node->varlist_end();
1945 I != E; ++I)
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001946 Visitor->AddStmt(*I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001947}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001948
1949void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001950 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001951}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001952void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1953 const OMPFirstprivateClause *C) {
1954 VisitOMPClauseList(C);
1955}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001956void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001957 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001958}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001959}
Alexey Bataev756c1962013-09-24 03:17:45 +00001960
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001961void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1962 unsigned size = WL.size();
1963 OMPClauseEnqueue Visitor(this);
1964 Visitor.Visit(S);
1965 if (size == WL.size())
1966 return;
1967 // Now reverse the entries we just added. This will match the DFS
1968 // ordering performed by the worklist.
1969 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1970 std::reverse(I, E);
1971}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001972void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001973 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1974}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001975void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001976 AddDecl(B->getBlockDecl());
1977}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001978void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001979 EnqueueChildren(E);
1980 AddTypeLoc(E->getTypeSourceInfo());
1981}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001982void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1983 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001984 E = S->body_rend(); I != E; ++I) {
1985 AddStmt(*I);
1986 }
1987}
1988void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001989VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001990 AddStmt(S->getSubStmt());
1991 AddDeclarationNameInfo(S);
1992 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1993 AddNestedNameSpecifierLoc(QualifierLoc);
1994}
1995
1996void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001997VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001998 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1999 AddDeclarationNameInfo(E);
2000 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2001 AddNestedNameSpecifierLoc(QualifierLoc);
2002 if (!E->isImplicitAccess())
2003 AddStmt(E->getBase());
2004}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002005void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002006 // Enqueue the initializer , if any.
2007 AddStmt(E->getInitializer());
2008 // Enqueue the array size, if any.
2009 AddStmt(E->getArraySize());
2010 // Enqueue the allocated type.
2011 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2012 // Enqueue the placement arguments.
2013 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2014 AddStmt(E->getPlacementArg(I-1));
2015}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002016void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002017 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2018 AddStmt(CE->getArg(I-1));
2019 AddStmt(CE->getCallee());
2020 AddStmt(CE->getArg(0));
2021}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002022void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2023 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002024 // Visit the name of the type being destroyed.
2025 AddTypeLoc(E->getDestroyedTypeInfo());
2026 // Visit the scope type that looks disturbingly like the nested-name-specifier
2027 // but isn't.
2028 AddTypeLoc(E->getScopeTypeInfo());
2029 // Visit the nested-name-specifier.
2030 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2031 AddNestedNameSpecifierLoc(QualifierLoc);
2032 // Visit base expression.
2033 AddStmt(E->getBase());
2034}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002035void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2036 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002037 AddTypeLoc(E->getTypeSourceInfo());
2038}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002039void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2040 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002041 EnqueueChildren(E);
2042 AddTypeLoc(E->getTypeSourceInfo());
2043}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002044void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002045 EnqueueChildren(E);
2046 if (E->isTypeOperand())
2047 AddTypeLoc(E->getTypeOperandSourceInfo());
2048}
2049
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002050void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2051 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002052 EnqueueChildren(E);
2053 AddTypeLoc(E->getTypeSourceInfo());
2054}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002055void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002056 EnqueueChildren(E);
2057 if (E->isTypeOperand())
2058 AddTypeLoc(E->getTypeOperandSourceInfo());
2059}
2060
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002061void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002062 EnqueueChildren(S);
2063 AddDecl(S->getExceptionDecl());
2064}
2065
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002066void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002067 if (DR->hasExplicitTemplateArgs()) {
2068 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2069 }
2070 WL.push_back(DeclRefExprParts(DR, Parent));
2071}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002072void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2073 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002074 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2075 AddDeclarationNameInfo(E);
2076 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2077}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002078void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002079 unsigned size = WL.size();
2080 bool isFirst = true;
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002081 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00002082 D != DEnd; ++D) {
2083 AddDecl(*D, isFirst);
2084 isFirst = false;
2085 }
2086 if (size == WL.size())
2087 return;
2088 // Now reverse the entries we just added. This will match the DFS
2089 // ordering performed by the worklist.
2090 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2091 std::reverse(I, E);
2092}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002093void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002094 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002095 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002096 D = E->designators_rbegin(), DEnd = E->designators_rend();
2097 D != DEnd; ++D) {
2098 if (D->isFieldDesignator()) {
2099 if (FieldDecl *Field = D->getField())
2100 AddMemberRef(Field, D->getFieldLoc());
2101 continue;
2102 }
2103 if (D->isArrayDesignator()) {
2104 AddStmt(E->getArrayIndex(*D));
2105 continue;
2106 }
2107 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2108 AddStmt(E->getArrayRangeEnd(*D));
2109 AddStmt(E->getArrayRangeStart(*D));
2110 }
2111}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002112void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002113 EnqueueChildren(E);
2114 AddTypeLoc(E->getTypeInfoAsWritten());
2115}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002116void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002117 AddStmt(FS->getBody());
2118 AddStmt(FS->getInc());
2119 AddStmt(FS->getCond());
2120 AddDecl(FS->getConditionVariable());
2121 AddStmt(FS->getInit());
2122}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002123void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002124 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2125}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002126void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002127 AddStmt(If->getElse());
2128 AddStmt(If->getThen());
2129 AddStmt(If->getCond());
2130 AddDecl(If->getConditionVariable());
2131}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002132void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002133 // We care about the syntactic form of the initializer list, only.
2134 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2135 IE = Syntactic;
2136 EnqueueChildren(IE);
2137}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002138void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002139 WL.push_back(MemberExprParts(M, Parent));
2140
2141 // If the base of the member access expression is an implicit 'this', don't
2142 // visit it.
2143 // FIXME: If we ever want to show these implicit accesses, this will be
2144 // unfortunate. However, clang_getCursor() relies on this behavior.
2145 if (!M->isImplicitAccess())
2146 AddStmt(M->getBase());
2147}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002148void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002149 AddTypeLoc(E->getEncodedTypeSourceInfo());
2150}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002151void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002152 EnqueueChildren(M);
2153 AddTypeLoc(M->getClassReceiverTypeInfo());
2154}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002155void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002156 // Visit the components of the offsetof expression.
2157 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2158 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2159 const OffsetOfNode &Node = E->getComponent(I-1);
2160 switch (Node.getKind()) {
2161 case OffsetOfNode::Array:
2162 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2163 break;
2164 case OffsetOfNode::Field:
2165 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2166 break;
2167 case OffsetOfNode::Identifier:
2168 case OffsetOfNode::Base:
2169 continue;
2170 }
2171 }
2172 // Visit the type into which we're computing the offset.
2173 AddTypeLoc(E->getTypeSourceInfo());
2174}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002175void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002176 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2177 WL.push_back(OverloadExprParts(E, Parent));
2178}
2179void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002180 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002181 EnqueueChildren(E);
2182 if (E->isArgumentType())
2183 AddTypeLoc(E->getArgumentTypeInfo());
2184}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002185void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002186 EnqueueChildren(S);
2187}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002188void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002189 AddStmt(S->getBody());
2190 AddStmt(S->getCond());
2191 AddDecl(S->getConditionVariable());
2192}
2193
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002194void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002195 AddStmt(W->getBody());
2196 AddStmt(W->getCond());
2197 AddDecl(W->getConditionVariable());
2198}
2199
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002200void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002201 for (unsigned I = E->getNumArgs(); I > 0; --I)
2202 AddTypeLoc(E->getArg(I-1));
2203}
2204
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002205void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002206 AddTypeLoc(E->getQueriedTypeSourceInfo());
2207}
2208
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002209void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002210 EnqueueChildren(E);
2211}
2212
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002213void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002214 VisitOverloadExpr(U);
2215 if (!U->isImplicitAccess())
2216 AddStmt(U->getBase());
2217}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 AddStmt(E->getSubExpr());
2220 AddTypeLoc(E->getWrittenTypeInfo());
2221}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002222void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002223 WL.push_back(SizeOfPackExprParts(E, Parent));
2224}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002225void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002226 // If the opaque value has a source expression, just transparently
2227 // visit that. This is useful for (e.g.) pseudo-object expressions.
2228 if (Expr *SourceExpr = E->getSourceExpr())
2229 return Visit(SourceExpr);
2230}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002231void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002232 AddStmt(E->getBody());
2233 WL.push_back(LambdaExprParts(E, Parent));
2234}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002235void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002236 // Treat the expression like its syntactic form.
2237 Visit(E->getSyntacticForm());
2238}
2239
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002240void EnqueueVisitor::VisitOMPExecutableDirective(
2241 const OMPExecutableDirective *D) {
2242 EnqueueChildren(D);
2243 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2244 E = D->clauses().end();
2245 I != E; ++I)
2246 EnqueueChildren(*I);
2247}
2248
2249void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2250 VisitOMPExecutableDirective(D);
2251}
2252
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002253void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2254 VisitOMPExecutableDirective(D);
2255}
2256
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002257void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002258 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2259}
2260
2261bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2262 if (RegionOfInterest.isValid()) {
2263 SourceRange Range = getRawCursorExtent(C);
2264 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2265 return false;
2266 }
2267 return true;
2268}
2269
2270bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2271 while (!WL.empty()) {
2272 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002273 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002274
2275 // Set the Parent field, then back to its old value once we're done.
2276 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2277
2278 switch (LI.getKind()) {
2279 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002280 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002281 if (!D)
2282 continue;
2283
2284 // For now, perform default visitation for Decls.
2285 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2286 cast<DeclVisit>(&LI)->isFirst())))
2287 return true;
2288
2289 continue;
2290 }
2291 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2292 const ASTTemplateArgumentListInfo *ArgList =
2293 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2294 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2295 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2296 Arg != ArgEnd; ++Arg) {
2297 if (VisitTemplateArgumentLoc(*Arg))
2298 return true;
2299 }
2300 continue;
2301 }
2302 case VisitorJob::TypeLocVisitKind: {
2303 // Perform default visitation for TypeLocs.
2304 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2305 return true;
2306 continue;
2307 }
2308 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002309 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002310 if (LabelStmt *stmt = LS->getStmt()) {
2311 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2312 TU))) {
2313 return true;
2314 }
2315 }
2316 continue;
2317 }
2318
2319 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2320 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2321 if (VisitNestedNameSpecifierLoc(V->get()))
2322 return true;
2323 continue;
2324 }
2325
2326 case VisitorJob::DeclarationNameInfoVisitKind: {
2327 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2328 ->get()))
2329 return true;
2330 continue;
2331 }
2332 case VisitorJob::MemberRefVisitKind: {
2333 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2334 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2335 return true;
2336 continue;
2337 }
2338 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002339 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002340 if (!S)
2341 continue;
2342
2343 // Update the current cursor.
2344 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2345 if (!IsInRegionOfInterest(Cursor))
2346 continue;
2347 switch (Visitor(Cursor, Parent, ClientData)) {
2348 case CXChildVisit_Break: return true;
2349 case CXChildVisit_Continue: break;
2350 case CXChildVisit_Recurse:
2351 if (PostChildrenVisitor)
2352 WL.push_back(PostChildrenVisit(0, Cursor));
2353 EnqueueWorkList(WL, S);
2354 break;
2355 }
2356 continue;
2357 }
2358 case VisitorJob::MemberExprPartsKind: {
2359 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002360 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002361
2362 // Visit the nested-name-specifier
2363 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2364 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2365 return true;
2366
2367 // Visit the declaration name.
2368 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2369 return true;
2370
2371 // Visit the explicitly-specified template arguments, if any.
2372 if (M->hasExplicitTemplateArgs()) {
2373 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2374 *ArgEnd = Arg + M->getNumTemplateArgs();
2375 Arg != ArgEnd; ++Arg) {
2376 if (VisitTemplateArgumentLoc(*Arg))
2377 return true;
2378 }
2379 }
2380 continue;
2381 }
2382 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002383 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002384 // Visit nested-name-specifier, if present.
2385 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2386 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2387 return true;
2388 // Visit declaration name.
2389 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2390 return true;
2391 continue;
2392 }
2393 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002394 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002395 // Visit the nested-name-specifier.
2396 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2397 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2398 return true;
2399 // Visit the declaration name.
2400 if (VisitDeclarationNameInfo(O->getNameInfo()))
2401 return true;
2402 // Visit the overloaded declaration reference.
2403 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2404 return true;
2405 continue;
2406 }
2407 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002408 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002409 NamedDecl *Pack = E->getPack();
2410 if (isa<TemplateTypeParmDecl>(Pack)) {
2411 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2412 E->getPackLoc(), TU)))
2413 return true;
2414
2415 continue;
2416 }
2417
2418 if (isa<TemplateTemplateParmDecl>(Pack)) {
2419 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2420 E->getPackLoc(), TU)))
2421 return true;
2422
2423 continue;
2424 }
2425
2426 // Non-type template parameter packs and function parameter packs are
2427 // treated like DeclRefExpr cursors.
2428 continue;
2429 }
2430
2431 case VisitorJob::LambdaExprPartsKind: {
2432 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002433 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002434 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2435 CEnd = E->explicit_capture_end();
2436 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002437 // FIXME: Lambda init-captures.
2438 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002440
Guy Benyei11169dd2012-12-18 14:30:41 +00002441 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2442 C->getLocation(),
2443 TU)))
2444 return true;
2445 }
2446
2447 // Visit parameters and return type, if present.
2448 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2449 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2450 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2451 // Visit the whole type.
2452 if (Visit(TL))
2453 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002454 } else if (FunctionProtoTypeLoc Proto =
2455 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002456 if (E->hasExplicitParameters()) {
2457 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002458 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2459 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002460 return true;
2461 } else {
2462 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002463 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002464 return true;
2465 }
2466 }
2467 }
2468 break;
2469 }
2470
2471 case VisitorJob::PostChildrenVisitKind:
2472 if (PostChildrenVisitor(Parent, ClientData))
2473 return true;
2474 break;
2475 }
2476 }
2477 return false;
2478}
2479
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002480bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002481 VisitorWorkList *WL = 0;
2482 if (!WorkListFreeList.empty()) {
2483 WL = WorkListFreeList.back();
2484 WL->clear();
2485 WorkListFreeList.pop_back();
2486 }
2487 else {
2488 WL = new VisitorWorkList();
2489 WorkListCache.push_back(WL);
2490 }
2491 EnqueueWorkList(*WL, S);
2492 bool result = RunVisitorWorkList(*WL);
2493 WorkListFreeList.push_back(WL);
2494 return result;
2495}
2496
2497namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002498typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002499RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2500 const DeclarationNameInfo &NI,
2501 const SourceRange &QLoc,
2502 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2503 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2504 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2505 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2506
2507 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2508
2509 RefNamePieces Pieces;
2510
2511 if (WantQualifier && QLoc.isValid())
2512 Pieces.push_back(QLoc);
2513
2514 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2515 Pieces.push_back(NI.getLoc());
2516
2517 if (WantTemplateArgs && TemplateArgs)
2518 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2519 TemplateArgs->RAngleLoc));
2520
2521 if (Kind == DeclarationName::CXXOperatorName) {
2522 Pieces.push_back(SourceLocation::getFromRawEncoding(
2523 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2524 Pieces.push_back(SourceLocation::getFromRawEncoding(
2525 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2526 }
2527
2528 if (WantSinglePiece) {
2529 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2530 Pieces.clear();
2531 Pieces.push_back(R);
2532 }
2533
2534 return Pieces;
2535}
2536}
2537
2538//===----------------------------------------------------------------------===//
2539// Misc. API hooks.
2540//===----------------------------------------------------------------------===//
2541
2542static llvm::sys::Mutex EnableMultithreadingMutex;
2543static bool EnabledMultithreading;
2544
Chad Rosier05c71aa2013-03-27 18:28:23 +00002545static void fatal_error_handler(void *user_data, const std::string& reason,
2546 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002547 // Write the result out to stderr avoiding errs() because raw_ostreams can
2548 // call report_fatal_error.
2549 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2550 ::abort();
2551}
2552
2553extern "C" {
2554CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2555 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002556 // We use crash recovery to make some of our APIs more reliable, implicitly
2557 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002558 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2559 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002560
2561 // Enable support for multithreading in LLVM.
2562 {
2563 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2564 if (!EnabledMultithreading) {
2565 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2566 llvm::llvm_start_multithreaded();
2567 EnabledMultithreading = true;
2568 }
2569 }
2570
2571 CIndexer *CIdxr = new CIndexer();
2572 if (excludeDeclarationsFromPCH)
2573 CIdxr->setOnlyLocalDecls();
2574 if (displayDiagnostics)
2575 CIdxr->setDisplayDiagnostics();
2576
2577 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2578 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2579 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2580 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2581 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2582 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2583
2584 return CIdxr;
2585}
2586
2587void clang_disposeIndex(CXIndex CIdx) {
2588 if (CIdx)
2589 delete static_cast<CIndexer *>(CIdx);
2590}
2591
2592void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2593 if (CIdx)
2594 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2595}
2596
2597unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2598 if (CIdx)
2599 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2600 return 0;
2601}
2602
2603void clang_toggleCrashRecovery(unsigned isEnabled) {
2604 if (isEnabled)
2605 llvm::CrashRecoveryContext::Enable();
2606 else
2607 llvm::CrashRecoveryContext::Disable();
2608}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002609
Guy Benyei11169dd2012-12-18 14:30:41 +00002610CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2611 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002612 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002613 enum CXErrorCode Result =
2614 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002615 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002616 assert((TU && Result == CXError_Success) ||
2617 (!TU && Result != CXError_Success));
2618 return TU;
2619}
2620
2621enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2622 const char *ast_filename,
2623 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002624 if (out_TU)
2625 *out_TU = NULL;
2626
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002627 if (!CIdx || !ast_filename || !out_TU)
2628 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002629
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002630 LOG_FUNC_SECTION {
2631 *Log << ast_filename;
2632 }
2633
Guy Benyei11169dd2012-12-18 14:30:41 +00002634 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2635 FileSystemOptions FileSystemOpts;
2636
2637 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002638 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002639 CXXIdx->getOnlyLocalDecls(), None,
2640 /*CaptureDiagnostics=*/true,
2641 /*AllowPCHWithCompilerErrors=*/true,
2642 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002643 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2644 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002645}
2646
2647unsigned clang_defaultEditingTranslationUnitOptions() {
2648 return CXTranslationUnit_PrecompiledPreamble |
2649 CXTranslationUnit_CacheCompletionResults;
2650}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002651
Guy Benyei11169dd2012-12-18 14:30:41 +00002652CXTranslationUnit
2653clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2654 const char *source_filename,
2655 int num_command_line_args,
2656 const char * const *command_line_args,
2657 unsigned num_unsaved_files,
2658 struct CXUnsavedFile *unsaved_files) {
2659 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2660 return clang_parseTranslationUnit(CIdx, source_filename,
2661 command_line_args, num_command_line_args,
2662 unsaved_files, num_unsaved_files,
2663 Options);
2664}
2665
2666struct ParseTranslationUnitInfo {
2667 CXIndex CIdx;
2668 const char *source_filename;
2669 const char *const *command_line_args;
2670 int num_command_line_args;
2671 struct CXUnsavedFile *unsaved_files;
2672 unsigned num_unsaved_files;
2673 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002674 CXTranslationUnit *out_TU;
2675 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002676};
2677static void clang_parseTranslationUnit_Impl(void *UserData) {
2678 ParseTranslationUnitInfo *PTUI =
2679 static_cast<ParseTranslationUnitInfo*>(UserData);
2680 CXIndex CIdx = PTUI->CIdx;
2681 const char *source_filename = PTUI->source_filename;
2682 const char * const *command_line_args = PTUI->command_line_args;
2683 int num_command_line_args = PTUI->num_command_line_args;
2684 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2685 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2686 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002687 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002688
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002689 // Set up the initial return values.
2690 if (out_TU)
2691 *out_TU = NULL;
2692 PTUI->result = CXError_Failure;
2693
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002694 // Check arguments.
2695 if (!CIdx || !out_TU ||
2696 (unsaved_files == NULL && num_unsaved_files != 0)) {
2697 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002698 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002699 }
2700
Guy Benyei11169dd2012-12-18 14:30:41 +00002701 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2702
2703 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2704 setThreadBackgroundPriority();
2705
2706 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2707 // FIXME: Add a flag for modules.
2708 TranslationUnitKind TUKind
2709 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002710 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002711 = options & CXTranslationUnit_CacheCompletionResults;
2712 bool IncludeBriefCommentsInCodeCompletion
2713 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2714 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2715 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2716
2717 // Configure the diagnostics.
2718 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002719 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002720
2721 // Recover resources if we crash before exiting this function.
2722 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2723 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2724 DiagCleanup(Diags.getPtr());
2725
2726 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2727 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2728
2729 // Recover resources if we crash before exiting this function.
2730 llvm::CrashRecoveryContextCleanupRegistrar<
2731 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2732
2733 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2734 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2735 const llvm::MemoryBuffer *Buffer
2736 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2737 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2738 Buffer));
2739 }
2740
2741 OwningPtr<std::vector<const char *> >
2742 Args(new std::vector<const char*>());
2743
2744 // Recover resources if we crash before exiting this method.
2745 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2746 ArgsCleanup(Args.get());
2747
2748 // Since the Clang C library is primarily used by batch tools dealing with
2749 // (often very broken) source code, where spell-checking can have a
2750 // significant negative impact on performance (particularly when
2751 // precompiled headers are involved), we disable it by default.
2752 // Only do this if we haven't found a spell-checking-related argument.
2753 bool FoundSpellCheckingArgument = false;
2754 for (int I = 0; I != num_command_line_args; ++I) {
2755 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2756 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2757 FoundSpellCheckingArgument = true;
2758 break;
2759 }
2760 }
2761 if (!FoundSpellCheckingArgument)
2762 Args->push_back("-fno-spell-checking");
2763
2764 Args->insert(Args->end(), command_line_args,
2765 command_line_args + num_command_line_args);
2766
2767 // The 'source_filename' argument is optional. If the caller does not
2768 // specify it then it is assumed that the source file is specified
2769 // in the actual argument list.
2770 // Put the source file after command_line_args otherwise if '-x' flag is
2771 // present it will be unused.
2772 if (source_filename)
2773 Args->push_back(source_filename);
2774
2775 // Do we need the detailed preprocessing record?
2776 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2777 Args->push_back("-Xclang");
2778 Args->push_back("-detailed-preprocessing-record");
2779 }
2780
2781 unsigned NumErrors = Diags->getClient()->getNumErrors();
2782 OwningPtr<ASTUnit> ErrUnit;
2783 OwningPtr<ASTUnit> Unit(
2784 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2785 /* vector::data() not portable */,
2786 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2787 Diags,
2788 CXXIdx->getClangResourcesPath(),
2789 CXXIdx->getOnlyLocalDecls(),
2790 /*CaptureDiagnostics=*/true,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002791 *RemappedFiles.get(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002792 /*RemappedFilesKeepOriginalName=*/true,
2793 PrecompilePreamble,
2794 TUKind,
Alp Toker8c8a8752013-12-03 06:53:35 +00002795 CacheCodeCompletionResults,
Guy Benyei11169dd2012-12-18 14:30:41 +00002796 IncludeBriefCommentsInCodeCompletion,
2797 /*AllowPCHWithCompilerErrors=*/true,
2798 SkipFunctionBodies,
2799 /*UserFilesAreVolatile=*/true,
2800 ForSerialization,
2801 &ErrUnit));
2802
2803 if (NumErrors != Diags->getClient()->getNumErrors()) {
2804 // Make sure to check that 'Unit' is non-NULL.
2805 if (CXXIdx->getDisplayDiagnostics())
2806 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2807 }
2808
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002809 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2810 PTUI->result = CXError_ASTReadError;
2811 } else {
2812 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.take());
2813 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2814 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002815}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002816
2817CXTranslationUnit
2818clang_parseTranslationUnit(CXIndex CIdx,
2819 const char *source_filename,
2820 const char *const *command_line_args,
2821 int num_command_line_args,
2822 struct CXUnsavedFile *unsaved_files,
2823 unsigned num_unsaved_files,
2824 unsigned options) {
2825 CXTranslationUnit TU;
2826 enum CXErrorCode Result = clang_parseTranslationUnit2(
2827 CIdx, source_filename, command_line_args, num_command_line_args,
2828 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002829 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002830 assert((TU && Result == CXError_Success) ||
2831 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002832 return TU;
2833}
2834
2835enum CXErrorCode clang_parseTranslationUnit2(
2836 CXIndex CIdx,
2837 const char *source_filename,
2838 const char *const *command_line_args,
2839 int num_command_line_args,
2840 struct CXUnsavedFile *unsaved_files,
2841 unsigned num_unsaved_files,
2842 unsigned options,
2843 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002844 LOG_FUNC_SECTION {
2845 *Log << source_filename << ": ";
2846 for (int i = 0; i != num_command_line_args; ++i)
2847 *Log << command_line_args[i] << " ";
2848 }
2849
Guy Benyei11169dd2012-12-18 14:30:41 +00002850 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2851 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002852 num_unsaved_files, options, out_TU,
2853 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002854 llvm::CrashRecoveryContext CRC;
2855
2856 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2857 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2858 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2859 fprintf(stderr, " 'command_line_args' : [");
2860 for (int i = 0; i != num_command_line_args; ++i) {
2861 if (i)
2862 fprintf(stderr, ", ");
2863 fprintf(stderr, "'%s'", command_line_args[i]);
2864 }
2865 fprintf(stderr, "],\n");
2866 fprintf(stderr, " 'unsaved_files' : [");
2867 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2868 if (i)
2869 fprintf(stderr, ", ");
2870 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2871 unsaved_files[i].Length);
2872 }
2873 fprintf(stderr, "],\n");
2874 fprintf(stderr, " 'options' : %d,\n", options);
2875 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002876
2877 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002878 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002879 if (CXTranslationUnit *TU = PTUI.out_TU)
2880 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002881 }
2882
2883 return PTUI.result;
2884}
2885
2886unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2887 return CXSaveTranslationUnit_None;
2888}
2889
2890namespace {
2891
2892struct SaveTranslationUnitInfo {
2893 CXTranslationUnit TU;
2894 const char *FileName;
2895 unsigned options;
2896 CXSaveError result;
2897};
2898
2899}
2900
2901static void clang_saveTranslationUnit_Impl(void *UserData) {
2902 SaveTranslationUnitInfo *STUI =
2903 static_cast<SaveTranslationUnitInfo*>(UserData);
2904
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002905 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002906 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2907 setThreadBackgroundPriority();
2908
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002909 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002910 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2911}
2912
2913int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2914 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002915 LOG_FUNC_SECTION {
2916 *Log << TU << ' ' << FileName;
2917 }
2918
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002919 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002920 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002921 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002922 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002923
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002924 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002925 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2926 if (!CXXUnit->hasSema())
2927 return CXSaveError_InvalidTU;
2928
2929 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2930
2931 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2932 getenv("LIBCLANG_NOTHREADS")) {
2933 clang_saveTranslationUnit_Impl(&STUI);
2934
2935 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2936 PrintLibclangResourceUsage(TU);
2937
2938 return STUI.result;
2939 }
2940
2941 // We have an AST that has invalid nodes due to compiler errors.
2942 // Use a crash recovery thread for protection.
2943
2944 llvm::CrashRecoveryContext CRC;
2945
2946 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2947 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2948 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2949 fprintf(stderr, " 'options' : %d,\n", options);
2950 fprintf(stderr, "}\n");
2951
2952 return CXSaveError_Unknown;
2953
2954 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2955 PrintLibclangResourceUsage(TU);
2956 }
2957
2958 return STUI.result;
2959}
2960
2961void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2962 if (CTUnit) {
2963 // If the translation unit has been marked as unsafe to free, just discard
2964 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002965 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2966 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002967 return;
2968
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002969 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002970 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002971 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2972 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002973 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002974 delete CTUnit;
2975 }
2976}
2977
2978unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2979 return CXReparse_None;
2980}
2981
2982struct ReparseTranslationUnitInfo {
2983 CXTranslationUnit TU;
2984 unsigned num_unsaved_files;
2985 struct CXUnsavedFile *unsaved_files;
2986 unsigned options;
2987 int result;
2988};
2989
2990static void clang_reparseTranslationUnit_Impl(void *UserData) {
2991 ReparseTranslationUnitInfo *RTUI =
2992 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002993 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002994
Guy Benyei11169dd2012-12-18 14:30:41 +00002995 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002996 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2997 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2998 unsigned options = RTUI->options;
2999 (void) options;
3000
3001 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003002 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003003 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003004 RTUI->result = CXError_InvalidArguments;
3005 return;
3006 }
3007 if (unsaved_files == NULL && num_unsaved_files != 0) {
3008 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003009 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003010 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003011
3012 // Reset the associated diagnostics.
3013 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3014 TU->Diagnostics = 0;
3015
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003016 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003017 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3018 setThreadBackgroundPriority();
3019
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003020 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003021 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3022
3023 OwningPtr<std::vector<ASTUnit::RemappedFile> >
3024 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
3025
3026 // Recover resources if we crash before exiting this function.
3027 llvm::CrashRecoveryContextCleanupRegistrar<
3028 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3029
3030 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3031 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3032 const llvm::MemoryBuffer *Buffer
3033 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3034 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3035 Buffer));
3036 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003037
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003038 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003039 RTUI->result = CXError_Success;
3040 else if (isASTReadError(CXXUnit))
3041 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003042}
3043
3044int clang_reparseTranslationUnit(CXTranslationUnit TU,
3045 unsigned num_unsaved_files,
3046 struct CXUnsavedFile *unsaved_files,
3047 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003048 LOG_FUNC_SECTION {
3049 *Log << TU;
3050 }
3051
Guy Benyei11169dd2012-12-18 14:30:41 +00003052 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003053 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003054
3055 if (getenv("LIBCLANG_NOTHREADS")) {
3056 clang_reparseTranslationUnit_Impl(&RTUI);
3057 return RTUI.result;
3058 }
3059
3060 llvm::CrashRecoveryContext CRC;
3061
3062 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3063 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003064 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003065 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003066 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3067 PrintLibclangResourceUsage(TU);
3068
3069 return RTUI.result;
3070}
3071
3072
3073CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003074 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003075 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003076 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003077 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003078
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003079 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003080 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003081}
3082
3083CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003084 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003085 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003086 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003087 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003088
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003089 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003090 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3091}
3092
3093} // end: extern "C"
3094
3095//===----------------------------------------------------------------------===//
3096// CXFile Operations.
3097//===----------------------------------------------------------------------===//
3098
3099extern "C" {
3100CXString clang_getFileName(CXFile SFile) {
3101 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003102 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003103
3104 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003105 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003106}
3107
3108time_t clang_getFileTime(CXFile SFile) {
3109 if (!SFile)
3110 return 0;
3111
3112 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3113 return FEnt->getModificationTime();
3114}
3115
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003116CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003117 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003118 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003119 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003120 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003121
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003122 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003123
3124 FileManager &FMgr = CXXUnit->getFileManager();
3125 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3126}
3127
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003128unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3129 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003130 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003131 LOG_BAD_TU(TU);
3132 return 0;
3133 }
3134
3135 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003136 return 0;
3137
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003138 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003139 FileEntry *FEnt = static_cast<FileEntry *>(file);
3140 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3141 .isFileMultipleIncludeGuarded(FEnt);
3142}
3143
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003144int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3145 if (!file || !outID)
3146 return 1;
3147
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003148 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003149 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3150 outID->data[0] = ID.getDevice();
3151 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003152 outID->data[2] = FEnt->getModificationTime();
3153 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003154}
3155
Guy Benyei11169dd2012-12-18 14:30:41 +00003156} // end: extern "C"
3157
3158//===----------------------------------------------------------------------===//
3159// CXCursor Operations.
3160//===----------------------------------------------------------------------===//
3161
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003162static const Decl *getDeclFromExpr(const Stmt *E) {
3163 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003164 return getDeclFromExpr(CE->getSubExpr());
3165
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003166 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003167 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003168 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003169 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003170 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003171 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003172 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003173 if (PRE->isExplicitProperty())
3174 return PRE->getExplicitProperty();
3175 // It could be messaging both getter and setter as in:
3176 // ++myobj.myprop;
3177 // in which case prefer to associate the setter since it is less obvious
3178 // from inspecting the source that the setter is going to get called.
3179 if (PRE->isMessagingSetter())
3180 return PRE->getImplicitPropertySetter();
3181 return PRE->getImplicitPropertyGetter();
3182 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003183 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003184 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003185 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003186 if (Expr *Src = OVE->getSourceExpr())
3187 return getDeclFromExpr(Src);
3188
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003189 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003190 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003191 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003192 if (!CE->isElidable())
3193 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003194 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003195 return OME->getMethodDecl();
3196
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003197 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003198 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003199 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003200 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3201 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003202 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003203 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3204 isa<ParmVarDecl>(SizeOfPack->getPack()))
3205 return SizeOfPack->getPack();
3206
3207 return 0;
3208}
3209
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003210static SourceLocation getLocationFromExpr(const Expr *E) {
3211 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003212 return getLocationFromExpr(CE->getSubExpr());
3213
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003214 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003215 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003216 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003217 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003218 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003219 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003220 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003221 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003222 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003223 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003224 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003225 return PropRef->getLocation();
3226
3227 return E->getLocStart();
3228}
3229
3230extern "C" {
3231
3232unsigned clang_visitChildren(CXCursor parent,
3233 CXCursorVisitor visitor,
3234 CXClientData client_data) {
3235 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3236 /*VisitPreprocessorLast=*/false);
3237 return CursorVis.VisitChildren(parent);
3238}
3239
3240#ifndef __has_feature
3241#define __has_feature(x) 0
3242#endif
3243#if __has_feature(blocks)
3244typedef enum CXChildVisitResult
3245 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3246
3247static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3248 CXClientData client_data) {
3249 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3250 return block(cursor, parent);
3251}
3252#else
3253// If we are compiled with a compiler that doesn't have native blocks support,
3254// define and call the block manually, so the
3255typedef struct _CXChildVisitResult
3256{
3257 void *isa;
3258 int flags;
3259 int reserved;
3260 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3261 CXCursor);
3262} *CXCursorVisitorBlock;
3263
3264static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3265 CXClientData client_data) {
3266 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3267 return block->invoke(block, cursor, parent);
3268}
3269#endif
3270
3271
3272unsigned clang_visitChildrenWithBlock(CXCursor parent,
3273 CXCursorVisitorBlock block) {
3274 return clang_visitChildren(parent, visitWithBlock, block);
3275}
3276
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003277static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003278 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003279 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003280
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003281 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003282 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003283 if (const ObjCPropertyImplDecl *PropImpl =
3284 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003285 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003286 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003287
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003288 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003289 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003290 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003291
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003292 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003293 }
3294
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003295 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003296 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003297
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003298 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003299 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3300 // and returns different names. NamedDecl returns the class name and
3301 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003302 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003303
3304 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003305 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003306
3307 SmallString<1024> S;
3308 llvm::raw_svector_ostream os(S);
3309 ND->printName(os);
3310
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003311 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003312}
3313
3314CXString clang_getCursorSpelling(CXCursor C) {
3315 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003316 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003317
3318 if (clang_isReference(C.kind)) {
3319 switch (C.kind) {
3320 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003321 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003322 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003323 }
3324 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003325 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003326 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003327 }
3328 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003329 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003330 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003331 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003332 }
3333 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003334 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003335 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003336 }
3337 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003338 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003339 assert(Type && "Missing type decl");
3340
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003341 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003342 getAsString());
3343 }
3344 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003345 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003346 assert(Template && "Missing template decl");
3347
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003348 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 }
3350
3351 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003352 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003353 assert(NS && "Missing namespace decl");
3354
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003355 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003356 }
3357
3358 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003359 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003360 assert(Field && "Missing member decl");
3361
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003362 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003363 }
3364
3365 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003366 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003367 assert(Label && "Missing label");
3368
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003369 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003370 }
3371
3372 case CXCursor_OverloadedDeclRef: {
3373 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003374 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3375 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003376 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003377 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003379 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003380 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003381 OverloadedTemplateStorage *Ovl
3382 = Storage.get<OverloadedTemplateStorage*>();
3383 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003384 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003385 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003386 }
3387
3388 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003389 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003390 assert(Var && "Missing variable decl");
3391
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003392 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003393 }
3394
3395 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003396 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003397 }
3398 }
3399
3400 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003401 const Expr *E = getCursorExpr(C);
3402
3403 if (C.kind == CXCursor_ObjCStringLiteral ||
3404 C.kind == CXCursor_StringLiteral) {
3405 const StringLiteral *SLit;
3406 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3407 SLit = OSL->getString();
3408 } else {
3409 SLit = cast<StringLiteral>(E);
3410 }
3411 SmallString<256> Buf;
3412 llvm::raw_svector_ostream OS(Buf);
3413 SLit->outputString(OS);
3414 return cxstring::createDup(OS.str());
3415 }
3416
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003417 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003418 if (D)
3419 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003420 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003421 }
3422
3423 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003424 const Stmt *S = getCursorStmt(C);
3425 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003426 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003427
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003428 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003429 }
3430
3431 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003432 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003433 ->getNameStart());
3434
3435 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003436 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003437 ->getNameStart());
3438
3439 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003440 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003441
3442 if (clang_isDeclaration(C.kind))
3443 return getDeclSpelling(getCursorDecl(C));
3444
3445 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003446 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003447 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003448 }
3449
3450 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003451 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003452 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003453 }
3454
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003455 if (C.kind == CXCursor_PackedAttr) {
3456 return cxstring::createRef("packed");
3457 }
3458
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003459 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003460}
3461
3462CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3463 unsigned pieceIndex,
3464 unsigned options) {
3465 if (clang_Cursor_isNull(C))
3466 return clang_getNullRange();
3467
3468 ASTContext &Ctx = getCursorContext(C);
3469
3470 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003471 const Stmt *S = getCursorStmt(C);
3472 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003473 if (pieceIndex > 0)
3474 return clang_getNullRange();
3475 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3476 }
3477
3478 return clang_getNullRange();
3479 }
3480
3481 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003482 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003483 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3484 if (pieceIndex >= ME->getNumSelectorLocs())
3485 return clang_getNullRange();
3486 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3487 }
3488 }
3489
3490 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3491 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003492 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003493 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3494 if (pieceIndex >= MD->getNumSelectorLocs())
3495 return clang_getNullRange();
3496 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3497 }
3498 }
3499
3500 if (C.kind == CXCursor_ObjCCategoryDecl ||
3501 C.kind == CXCursor_ObjCCategoryImplDecl) {
3502 if (pieceIndex > 0)
3503 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003504 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003505 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3506 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003507 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003508 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3509 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3510 }
3511
3512 if (C.kind == CXCursor_ModuleImportDecl) {
3513 if (pieceIndex > 0)
3514 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003515 if (const ImportDecl *ImportD =
3516 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003517 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3518 if (!Locs.empty())
3519 return cxloc::translateSourceRange(Ctx,
3520 SourceRange(Locs.front(), Locs.back()));
3521 }
3522 return clang_getNullRange();
3523 }
3524
3525 // FIXME: A CXCursor_InclusionDirective should give the location of the
3526 // filename, but we don't keep track of this.
3527
3528 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3529 // but we don't keep track of this.
3530
3531 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3532 // but we don't keep track of this.
3533
3534 // Default handling, give the location of the cursor.
3535
3536 if (pieceIndex > 0)
3537 return clang_getNullRange();
3538
3539 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3540 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3541 return cxloc::translateSourceRange(Ctx, Loc);
3542}
3543
3544CXString clang_getCursorDisplayName(CXCursor C) {
3545 if (!clang_isDeclaration(C.kind))
3546 return clang_getCursorSpelling(C);
3547
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003548 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003550 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003551
3552 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003553 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003554 D = FunTmpl->getTemplatedDecl();
3555
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003556 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003557 SmallString<64> Str;
3558 llvm::raw_svector_ostream OS(Str);
3559 OS << *Function;
3560 if (Function->getPrimaryTemplate())
3561 OS << "<>";
3562 OS << "(";
3563 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3564 if (I)
3565 OS << ", ";
3566 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3567 }
3568
3569 if (Function->isVariadic()) {
3570 if (Function->getNumParams())
3571 OS << ", ";
3572 OS << "...";
3573 }
3574 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003575 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003576 }
3577
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003578 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003579 SmallString<64> Str;
3580 llvm::raw_svector_ostream OS(Str);
3581 OS << *ClassTemplate;
3582 OS << "<";
3583 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3584 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3585 if (I)
3586 OS << ", ";
3587
3588 NamedDecl *Param = Params->getParam(I);
3589 if (Param->getIdentifier()) {
3590 OS << Param->getIdentifier()->getName();
3591 continue;
3592 }
3593
3594 // There is no parameter name, which makes this tricky. Try to come up
3595 // with something useful that isn't too long.
3596 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3597 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3598 else if (NonTypeTemplateParmDecl *NTTP
3599 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3600 OS << NTTP->getType().getAsString(Policy);
3601 else
3602 OS << "template<...> class";
3603 }
3604
3605 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003606 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003607 }
3608
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003609 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3611 // If the type was explicitly written, use that.
3612 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003613 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003614
Benjamin Kramer9170e912013-02-22 15:46:01 +00003615 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003616 llvm::raw_svector_ostream OS(Str);
3617 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003618 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003619 ClassSpec->getTemplateArgs().data(),
3620 ClassSpec->getTemplateArgs().size(),
3621 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003622 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 }
3624
3625 return clang_getCursorSpelling(C);
3626}
3627
3628CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3629 switch (Kind) {
3630 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003631 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003632 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003633 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003635 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003637 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003641 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003643 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003645 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003647 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003651 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003653 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003655 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003659 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003663 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003665 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003673 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003758 case CXCursor_ObjCSelfExpr:
3759 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003876 case CXCursor_PackedAttr:
3877 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003926 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003927 return cxstring::createRef("OMPParallelDirective");
3928 case CXCursor_OMPSimdDirective:
3929 return cxstring::createRef("OMPSimdDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 }
3931
3932 llvm_unreachable("Unhandled CXCursorKind");
3933}
3934
3935struct GetCursorData {
3936 SourceLocation TokenBeginLoc;
3937 bool PointsAtMacroArgExpansion;
3938 bool VisitedObjCPropertyImplDecl;
3939 SourceLocation VisitedDeclaratorDeclStartLoc;
3940 CXCursor &BestCursor;
3941
3942 GetCursorData(SourceManager &SM,
3943 SourceLocation tokenBegin, CXCursor &outputCursor)
3944 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3945 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3946 VisitedObjCPropertyImplDecl = false;
3947 }
3948};
3949
3950static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3951 CXCursor parent,
3952 CXClientData client_data) {
3953 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3954 CXCursor *BestCursor = &Data->BestCursor;
3955
3956 // If we point inside a macro argument we should provide info of what the
3957 // token is so use the actual cursor, don't replace it with a macro expansion
3958 // cursor.
3959 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3960 return CXChildVisit_Recurse;
3961
3962 if (clang_isDeclaration(cursor.kind)) {
3963 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003964 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3966 if (MD->isImplicit())
3967 return CXChildVisit_Break;
3968
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003969 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3971 // Check that when we have multiple @class references in the same line,
3972 // that later ones do not override the previous ones.
3973 // If we have:
3974 // @class Foo, Bar;
3975 // source ranges for both start at '@', so 'Bar' will end up overriding
3976 // 'Foo' even though the cursor location was at 'Foo'.
3977 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3978 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003979 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3981 if (PrevID != ID &&
3982 !PrevID->isThisDeclarationADefinition() &&
3983 !ID->isThisDeclarationADefinition())
3984 return CXChildVisit_Break;
3985 }
3986
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003987 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3989 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3990 // Check that when we have multiple declarators in the same line,
3991 // that later ones do not override the previous ones.
3992 // If we have:
3993 // int Foo, Bar;
3994 // source ranges for both start at 'int', so 'Bar' will end up overriding
3995 // 'Foo' even though the cursor location was at 'Foo'.
3996 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3997 return CXChildVisit_Break;
3998 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3999
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004000 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4002 (void)PropImp;
4003 // Check that when we have multiple @synthesize in the same line,
4004 // that later ones do not override the previous ones.
4005 // If we have:
4006 // @synthesize Foo, Bar;
4007 // source ranges for both start at '@', so 'Bar' will end up overriding
4008 // 'Foo' even though the cursor location was at 'Foo'.
4009 if (Data->VisitedObjCPropertyImplDecl)
4010 return CXChildVisit_Break;
4011 Data->VisitedObjCPropertyImplDecl = true;
4012 }
4013 }
4014
4015 if (clang_isExpression(cursor.kind) &&
4016 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004017 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 // Avoid having the cursor of an expression replace the declaration cursor
4019 // when the expression source range overlaps the declaration range.
4020 // This can happen for C++ constructor expressions whose range generally
4021 // include the variable declaration, e.g.:
4022 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4023 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4024 D->getLocation() == Data->TokenBeginLoc)
4025 return CXChildVisit_Break;
4026 }
4027 }
4028
4029 // If our current best cursor is the construction of a temporary object,
4030 // don't replace that cursor with a type reference, because we want
4031 // clang_getCursor() to point at the constructor.
4032 if (clang_isExpression(BestCursor->kind) &&
4033 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4034 cursor.kind == CXCursor_TypeRef) {
4035 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4036 // as having the actual point on the type reference.
4037 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4038 return CXChildVisit_Recurse;
4039 }
4040
4041 *BestCursor = cursor;
4042 return CXChildVisit_Recurse;
4043}
4044
4045CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004046 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004047 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004049 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004050
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004051 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4053
4054 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4055 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4056
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004057 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 CXFile SearchFile;
4059 unsigned SearchLine, SearchColumn;
4060 CXFile ResultFile;
4061 unsigned ResultLine, ResultColumn;
4062 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4063 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4064 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4065
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004066 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4067 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 &ResultColumn, 0);
4069 SearchFileName = clang_getFileName(SearchFile);
4070 ResultFileName = clang_getFileName(ResultFile);
4071 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4072 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004073 *Log << llvm::format("(%s:%d:%d) = %s",
4074 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4075 clang_getCString(KindSpelling))
4076 << llvm::format("(%s:%d:%d):%s%s",
4077 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4078 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 clang_disposeString(SearchFileName);
4080 clang_disposeString(ResultFileName);
4081 clang_disposeString(KindSpelling);
4082 clang_disposeString(USR);
4083
4084 CXCursor Definition = clang_getCursorDefinition(Result);
4085 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4086 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4087 CXString DefinitionKindSpelling
4088 = clang_getCursorKindSpelling(Definition.kind);
4089 CXFile DefinitionFile;
4090 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004091 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 &DefinitionLine, &DefinitionColumn, 0);
4093 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004094 *Log << llvm::format(" -> %s(%s:%d:%d)",
4095 clang_getCString(DefinitionKindSpelling),
4096 clang_getCString(DefinitionFileName),
4097 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 clang_disposeString(DefinitionFileName);
4099 clang_disposeString(DefinitionKindSpelling);
4100 }
4101 }
4102
4103 return Result;
4104}
4105
4106CXCursor clang_getNullCursor(void) {
4107 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4108}
4109
4110unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004111 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4112 // can't set consistently. For example, when visiting a DeclStmt we will set
4113 // it but we don't set it on the result of clang_getCursorDefinition for
4114 // a reference of the same declaration.
4115 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4116 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4117 // to provide that kind of info.
4118 if (clang_isDeclaration(X.kind))
4119 X.data[1] = 0;
4120 if (clang_isDeclaration(Y.kind))
4121 Y.data[1] = 0;
4122
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 return X == Y;
4124}
4125
4126unsigned clang_hashCursor(CXCursor C) {
4127 unsigned Index = 0;
4128 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4129 Index = 1;
4130
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004131 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 std::make_pair(C.kind, C.data[Index]));
4133}
4134
4135unsigned clang_isInvalid(enum CXCursorKind K) {
4136 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4137}
4138
4139unsigned clang_isDeclaration(enum CXCursorKind K) {
4140 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4141 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4142}
4143
4144unsigned clang_isReference(enum CXCursorKind K) {
4145 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4146}
4147
4148unsigned clang_isExpression(enum CXCursorKind K) {
4149 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4150}
4151
4152unsigned clang_isStatement(enum CXCursorKind K) {
4153 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4154}
4155
4156unsigned clang_isAttribute(enum CXCursorKind K) {
4157 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4158}
4159
4160unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4161 return K == CXCursor_TranslationUnit;
4162}
4163
4164unsigned clang_isPreprocessing(enum CXCursorKind K) {
4165 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4166}
4167
4168unsigned clang_isUnexposed(enum CXCursorKind K) {
4169 switch (K) {
4170 case CXCursor_UnexposedDecl:
4171 case CXCursor_UnexposedExpr:
4172 case CXCursor_UnexposedStmt:
4173 case CXCursor_UnexposedAttr:
4174 return true;
4175 default:
4176 return false;
4177 }
4178}
4179
4180CXCursorKind clang_getCursorKind(CXCursor C) {
4181 return C.kind;
4182}
4183
4184CXSourceLocation clang_getCursorLocation(CXCursor C) {
4185 if (clang_isReference(C.kind)) {
4186 switch (C.kind) {
4187 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004188 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 = getCursorObjCSuperClassRef(C);
4190 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4191 }
4192
4193 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004194 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 = getCursorObjCProtocolRef(C);
4196 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4197 }
4198
4199 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004200 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 = getCursorObjCClassRef(C);
4202 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4203 }
4204
4205 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004206 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4208 }
4209
4210 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004211 std::pair<const TemplateDecl *, SourceLocation> P =
4212 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004213 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4214 }
4215
4216 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004217 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4219 }
4220
4221 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004222 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004223 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4224 }
4225
4226 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004227 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004228 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4229 }
4230
4231 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004232 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004233 if (!BaseSpec)
4234 return clang_getNullLocation();
4235
4236 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4237 return cxloc::translateSourceLocation(getCursorContext(C),
4238 TSInfo->getTypeLoc().getBeginLoc());
4239
4240 return cxloc::translateSourceLocation(getCursorContext(C),
4241 BaseSpec->getLocStart());
4242 }
4243
4244 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004245 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004246 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4247 }
4248
4249 case CXCursor_OverloadedDeclRef:
4250 return cxloc::translateSourceLocation(getCursorContext(C),
4251 getCursorOverloadedDeclRef(C).second);
4252
4253 default:
4254 // FIXME: Need a way to enumerate all non-reference cases.
4255 llvm_unreachable("Missed a reference kind");
4256 }
4257 }
4258
4259 if (clang_isExpression(C.kind))
4260 return cxloc::translateSourceLocation(getCursorContext(C),
4261 getLocationFromExpr(getCursorExpr(C)));
4262
4263 if (clang_isStatement(C.kind))
4264 return cxloc::translateSourceLocation(getCursorContext(C),
4265 getCursorStmt(C)->getLocStart());
4266
4267 if (C.kind == CXCursor_PreprocessingDirective) {
4268 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4269 return cxloc::translateSourceLocation(getCursorContext(C), L);
4270 }
4271
4272 if (C.kind == CXCursor_MacroExpansion) {
4273 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004274 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004275 return cxloc::translateSourceLocation(getCursorContext(C), L);
4276 }
4277
4278 if (C.kind == CXCursor_MacroDefinition) {
4279 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4280 return cxloc::translateSourceLocation(getCursorContext(C), L);
4281 }
4282
4283 if (C.kind == CXCursor_InclusionDirective) {
4284 SourceLocation L
4285 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4286 return cxloc::translateSourceLocation(getCursorContext(C), L);
4287 }
4288
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004289 if (clang_isAttribute(C.kind)) {
4290 SourceLocation L
4291 = cxcursor::getCursorAttr(C)->getLocation();
4292 return cxloc::translateSourceLocation(getCursorContext(C), L);
4293 }
4294
Guy Benyei11169dd2012-12-18 14:30:41 +00004295 if (!clang_isDeclaration(C.kind))
4296 return clang_getNullLocation();
4297
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004298 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004299 if (!D)
4300 return clang_getNullLocation();
4301
4302 SourceLocation Loc = D->getLocation();
4303 // FIXME: Multiple variables declared in a single declaration
4304 // currently lack the information needed to correctly determine their
4305 // ranges when accounting for the type-specifier. We use context
4306 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4307 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004308 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004309 if (!cxcursor::isFirstInDeclGroup(C))
4310 Loc = VD->getLocation();
4311 }
4312
4313 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004314 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004315 Loc = MD->getSelectorStartLoc();
4316
4317 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4318}
4319
4320} // end extern "C"
4321
4322CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4323 assert(TU);
4324
4325 // Guard against an invalid SourceLocation, or we may assert in one
4326 // of the following calls.
4327 if (SLoc.isInvalid())
4328 return clang_getNullCursor();
4329
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004330 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004331
4332 // Translate the given source location to make it point at the beginning of
4333 // the token under the cursor.
4334 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4335 CXXUnit->getASTContext().getLangOpts());
4336
4337 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4338 if (SLoc.isValid()) {
4339 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4340 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4341 /*VisitPreprocessorLast=*/true,
4342 /*VisitIncludedEntities=*/false,
4343 SourceLocation(SLoc));
4344 CursorVis.visitFileRegion();
4345 }
4346
4347 return Result;
4348}
4349
4350static SourceRange getRawCursorExtent(CXCursor C) {
4351 if (clang_isReference(C.kind)) {
4352 switch (C.kind) {
4353 case CXCursor_ObjCSuperClassRef:
4354 return getCursorObjCSuperClassRef(C).second;
4355
4356 case CXCursor_ObjCProtocolRef:
4357 return getCursorObjCProtocolRef(C).second;
4358
4359 case CXCursor_ObjCClassRef:
4360 return getCursorObjCClassRef(C).second;
4361
4362 case CXCursor_TypeRef:
4363 return getCursorTypeRef(C).second;
4364
4365 case CXCursor_TemplateRef:
4366 return getCursorTemplateRef(C).second;
4367
4368 case CXCursor_NamespaceRef:
4369 return getCursorNamespaceRef(C).second;
4370
4371 case CXCursor_MemberRef:
4372 return getCursorMemberRef(C).second;
4373
4374 case CXCursor_CXXBaseSpecifier:
4375 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4376
4377 case CXCursor_LabelRef:
4378 return getCursorLabelRef(C).second;
4379
4380 case CXCursor_OverloadedDeclRef:
4381 return getCursorOverloadedDeclRef(C).second;
4382
4383 case CXCursor_VariableRef:
4384 return getCursorVariableRef(C).second;
4385
4386 default:
4387 // FIXME: Need a way to enumerate all non-reference cases.
4388 llvm_unreachable("Missed a reference kind");
4389 }
4390 }
4391
4392 if (clang_isExpression(C.kind))
4393 return getCursorExpr(C)->getSourceRange();
4394
4395 if (clang_isStatement(C.kind))
4396 return getCursorStmt(C)->getSourceRange();
4397
4398 if (clang_isAttribute(C.kind))
4399 return getCursorAttr(C)->getRange();
4400
4401 if (C.kind == CXCursor_PreprocessingDirective)
4402 return cxcursor::getCursorPreprocessingDirective(C);
4403
4404 if (C.kind == CXCursor_MacroExpansion) {
4405 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004406 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004407 return TU->mapRangeFromPreamble(Range);
4408 }
4409
4410 if (C.kind == CXCursor_MacroDefinition) {
4411 ASTUnit *TU = getCursorASTUnit(C);
4412 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4413 return TU->mapRangeFromPreamble(Range);
4414 }
4415
4416 if (C.kind == CXCursor_InclusionDirective) {
4417 ASTUnit *TU = getCursorASTUnit(C);
4418 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4419 return TU->mapRangeFromPreamble(Range);
4420 }
4421
4422 if (C.kind == CXCursor_TranslationUnit) {
4423 ASTUnit *TU = getCursorASTUnit(C);
4424 FileID MainID = TU->getSourceManager().getMainFileID();
4425 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4426 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4427 return SourceRange(Start, End);
4428 }
4429
4430 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004431 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004432 if (!D)
4433 return SourceRange();
4434
4435 SourceRange R = D->getSourceRange();
4436 // FIXME: Multiple variables declared in a single declaration
4437 // currently lack the information needed to correctly determine their
4438 // ranges when accounting for the type-specifier. We use context
4439 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4440 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004441 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004442 if (!cxcursor::isFirstInDeclGroup(C))
4443 R.setBegin(VD->getLocation());
4444 }
4445 return R;
4446 }
4447 return SourceRange();
4448}
4449
4450/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4451/// the decl-specifier-seq for declarations.
4452static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4453 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004454 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004455 if (!D)
4456 return SourceRange();
4457
4458 SourceRange R = D->getSourceRange();
4459
4460 // Adjust the start of the location for declarations preceded by
4461 // declaration specifiers.
4462 SourceLocation StartLoc;
4463 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4464 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4465 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004466 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004467 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4468 StartLoc = TI->getTypeLoc().getLocStart();
4469 }
4470
4471 if (StartLoc.isValid() && R.getBegin().isValid() &&
4472 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4473 R.setBegin(StartLoc);
4474
4475 // FIXME: Multiple variables declared in a single declaration
4476 // currently lack the information needed to correctly determine their
4477 // ranges when accounting for the type-specifier. We use context
4478 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4479 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004480 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004481 if (!cxcursor::isFirstInDeclGroup(C))
4482 R.setBegin(VD->getLocation());
4483 }
4484
4485 return R;
4486 }
4487
4488 return getRawCursorExtent(C);
4489}
4490
4491extern "C" {
4492
4493CXSourceRange clang_getCursorExtent(CXCursor C) {
4494 SourceRange R = getRawCursorExtent(C);
4495 if (R.isInvalid())
4496 return clang_getNullRange();
4497
4498 return cxloc::translateSourceRange(getCursorContext(C), R);
4499}
4500
4501CXCursor clang_getCursorReferenced(CXCursor C) {
4502 if (clang_isInvalid(C.kind))
4503 return clang_getNullCursor();
4504
4505 CXTranslationUnit tu = getCursorTU(C);
4506 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004507 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004508 if (!D)
4509 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004510 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004511 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004512 if (const ObjCPropertyImplDecl *PropImpl =
4513 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004514 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4515 return MakeCXCursor(Property, tu);
4516
4517 return C;
4518 }
4519
4520 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004521 const Expr *E = getCursorExpr(C);
4522 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004523 if (D) {
4524 CXCursor declCursor = MakeCXCursor(D, tu);
4525 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4526 declCursor);
4527 return declCursor;
4528 }
4529
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004530 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004531 return MakeCursorOverloadedDeclRef(Ovl, tu);
4532
4533 return clang_getNullCursor();
4534 }
4535
4536 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004537 const Stmt *S = getCursorStmt(C);
4538 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004539 if (LabelDecl *label = Goto->getLabel())
4540 if (LabelStmt *labelS = label->getStmt())
4541 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4542
4543 return clang_getNullCursor();
4544 }
4545
4546 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004547 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004548 return MakeMacroDefinitionCursor(Def, tu);
4549 }
4550
4551 if (!clang_isReference(C.kind))
4552 return clang_getNullCursor();
4553
4554 switch (C.kind) {
4555 case CXCursor_ObjCSuperClassRef:
4556 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4557
4558 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004559 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4560 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 return MakeCXCursor(Def, tu);
4562
4563 return MakeCXCursor(Prot, tu);
4564 }
4565
4566 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004567 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4568 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004569 return MakeCXCursor(Def, tu);
4570
4571 return MakeCXCursor(Class, tu);
4572 }
4573
4574 case CXCursor_TypeRef:
4575 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4576
4577 case CXCursor_TemplateRef:
4578 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4579
4580 case CXCursor_NamespaceRef:
4581 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4582
4583 case CXCursor_MemberRef:
4584 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4585
4586 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004587 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004588 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4589 tu ));
4590 }
4591
4592 case CXCursor_LabelRef:
4593 // FIXME: We end up faking the "parent" declaration here because we
4594 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004595 return MakeCXCursor(getCursorLabelRef(C).first,
4596 cxtu::getASTUnit(tu)->getASTContext()
4597 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004598 tu);
4599
4600 case CXCursor_OverloadedDeclRef:
4601 return C;
4602
4603 case CXCursor_VariableRef:
4604 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4605
4606 default:
4607 // We would prefer to enumerate all non-reference cursor kinds here.
4608 llvm_unreachable("Unhandled reference cursor kind");
4609 }
4610}
4611
4612CXCursor clang_getCursorDefinition(CXCursor C) {
4613 if (clang_isInvalid(C.kind))
4614 return clang_getNullCursor();
4615
4616 CXTranslationUnit TU = getCursorTU(C);
4617
4618 bool WasReference = false;
4619 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4620 C = clang_getCursorReferenced(C);
4621 WasReference = true;
4622 }
4623
4624 if (C.kind == CXCursor_MacroExpansion)
4625 return clang_getCursorReferenced(C);
4626
4627 if (!clang_isDeclaration(C.kind))
4628 return clang_getNullCursor();
4629
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004630 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 if (!D)
4632 return clang_getNullCursor();
4633
4634 switch (D->getKind()) {
4635 // Declaration kinds that don't really separate the notions of
4636 // declaration and definition.
4637 case Decl::Namespace:
4638 case Decl::Typedef:
4639 case Decl::TypeAlias:
4640 case Decl::TypeAliasTemplate:
4641 case Decl::TemplateTypeParm:
4642 case Decl::EnumConstant:
4643 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004644 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 case Decl::IndirectField:
4646 case Decl::ObjCIvar:
4647 case Decl::ObjCAtDefsField:
4648 case Decl::ImplicitParam:
4649 case Decl::ParmVar:
4650 case Decl::NonTypeTemplateParm:
4651 case Decl::TemplateTemplateParm:
4652 case Decl::ObjCCategoryImpl:
4653 case Decl::ObjCImplementation:
4654 case Decl::AccessSpec:
4655 case Decl::LinkageSpec:
4656 case Decl::ObjCPropertyImpl:
4657 case Decl::FileScopeAsm:
4658 case Decl::StaticAssert:
4659 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004660 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 case Decl::Label: // FIXME: Is this right??
4662 case Decl::ClassScopeFunctionSpecialization:
4663 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004664 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 return C;
4666
4667 // Declaration kinds that don't make any sense here, but are
4668 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004669 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004670 case Decl::TranslationUnit:
4671 break;
4672
4673 // Declaration kinds for which the definition is not resolvable.
4674 case Decl::UnresolvedUsingTypename:
4675 case Decl::UnresolvedUsingValue:
4676 break;
4677
4678 case Decl::UsingDirective:
4679 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4680 TU);
4681
4682 case Decl::NamespaceAlias:
4683 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4684
4685 case Decl::Enum:
4686 case Decl::Record:
4687 case Decl::CXXRecord:
4688 case Decl::ClassTemplateSpecialization:
4689 case Decl::ClassTemplatePartialSpecialization:
4690 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4691 return MakeCXCursor(Def, TU);
4692 return clang_getNullCursor();
4693
4694 case Decl::Function:
4695 case Decl::CXXMethod:
4696 case Decl::CXXConstructor:
4697 case Decl::CXXDestructor:
4698 case Decl::CXXConversion: {
4699 const FunctionDecl *Def = 0;
4700 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004701 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004702 return clang_getNullCursor();
4703 }
4704
Larisse Voufo39a1e502013-08-06 01:03:05 +00004705 case Decl::Var:
4706 case Decl::VarTemplateSpecialization:
4707 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004708 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004709 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004710 return MakeCXCursor(Def, TU);
4711 return clang_getNullCursor();
4712 }
4713
4714 case Decl::FunctionTemplate: {
4715 const FunctionDecl *Def = 0;
4716 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4717 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4718 return clang_getNullCursor();
4719 }
4720
4721 case Decl::ClassTemplate: {
4722 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4723 ->getDefinition())
4724 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4725 TU);
4726 return clang_getNullCursor();
4727 }
4728
Larisse Voufo39a1e502013-08-06 01:03:05 +00004729 case Decl::VarTemplate: {
4730 if (VarDecl *Def =
4731 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4732 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4733 return clang_getNullCursor();
4734 }
4735
Guy Benyei11169dd2012-12-18 14:30:41 +00004736 case Decl::Using:
4737 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4738 D->getLocation(), TU);
4739
4740 case Decl::UsingShadow:
4741 return clang_getCursorDefinition(
4742 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4743 TU));
4744
4745 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004746 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004747 if (Method->isThisDeclarationADefinition())
4748 return C;
4749
4750 // Dig out the method definition in the associated
4751 // @implementation, if we have it.
4752 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004753 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004754 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4755 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4756 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4757 Method->isInstanceMethod()))
4758 if (Def->isThisDeclarationADefinition())
4759 return MakeCXCursor(Def, TU);
4760
4761 return clang_getNullCursor();
4762 }
4763
4764 case Decl::ObjCCategory:
4765 if (ObjCCategoryImplDecl *Impl
4766 = cast<ObjCCategoryDecl>(D)->getImplementation())
4767 return MakeCXCursor(Impl, TU);
4768 return clang_getNullCursor();
4769
4770 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004771 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004772 return MakeCXCursor(Def, TU);
4773 return clang_getNullCursor();
4774
4775 case Decl::ObjCInterface: {
4776 // There are two notions of a "definition" for an Objective-C
4777 // class: the interface and its implementation. When we resolved a
4778 // reference to an Objective-C class, produce the @interface as
4779 // the definition; when we were provided with the interface,
4780 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004781 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004782 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004783 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004784 return MakeCXCursor(Def, TU);
4785 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4786 return MakeCXCursor(Impl, TU);
4787 return clang_getNullCursor();
4788 }
4789
4790 case Decl::ObjCProperty:
4791 // FIXME: We don't really know where to find the
4792 // ObjCPropertyImplDecls that implement this property.
4793 return clang_getNullCursor();
4794
4795 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004796 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004797 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004798 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004799 return MakeCXCursor(Def, TU);
4800
4801 return clang_getNullCursor();
4802
4803 case Decl::Friend:
4804 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4805 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4806 return clang_getNullCursor();
4807
4808 case Decl::FriendTemplate:
4809 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4810 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4811 return clang_getNullCursor();
4812 }
4813
4814 return clang_getNullCursor();
4815}
4816
4817unsigned clang_isCursorDefinition(CXCursor C) {
4818 if (!clang_isDeclaration(C.kind))
4819 return 0;
4820
4821 return clang_getCursorDefinition(C) == C;
4822}
4823
4824CXCursor clang_getCanonicalCursor(CXCursor C) {
4825 if (!clang_isDeclaration(C.kind))
4826 return C;
4827
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004828 if (const Decl *D = getCursorDecl(C)) {
4829 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004830 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4831 return MakeCXCursor(CatD, getCursorTU(C));
4832
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004833 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4834 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004835 return MakeCXCursor(IFD, getCursorTU(C));
4836
4837 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4838 }
4839
4840 return C;
4841}
4842
4843int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4844 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4845}
4846
4847unsigned clang_getNumOverloadedDecls(CXCursor C) {
4848 if (C.kind != CXCursor_OverloadedDeclRef)
4849 return 0;
4850
4851 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004852 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004853 return E->getNumDecls();
4854
4855 if (OverloadedTemplateStorage *S
4856 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4857 return S->size();
4858
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004859 const Decl *D = Storage.get<const Decl *>();
4860 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004861 return Using->shadow_size();
4862
4863 return 0;
4864}
4865
4866CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4867 if (cursor.kind != CXCursor_OverloadedDeclRef)
4868 return clang_getNullCursor();
4869
4870 if (index >= clang_getNumOverloadedDecls(cursor))
4871 return clang_getNullCursor();
4872
4873 CXTranslationUnit TU = getCursorTU(cursor);
4874 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004875 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004876 return MakeCXCursor(E->decls_begin()[index], TU);
4877
4878 if (OverloadedTemplateStorage *S
4879 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4880 return MakeCXCursor(S->begin()[index], TU);
4881
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004882 const Decl *D = Storage.get<const Decl *>();
4883 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004884 // FIXME: This is, unfortunately, linear time.
4885 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4886 std::advance(Pos, index);
4887 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4888 }
4889
4890 return clang_getNullCursor();
4891}
4892
4893void clang_getDefinitionSpellingAndExtent(CXCursor C,
4894 const char **startBuf,
4895 const char **endBuf,
4896 unsigned *startLine,
4897 unsigned *startColumn,
4898 unsigned *endLine,
4899 unsigned *endColumn) {
4900 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004901 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004902 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4903
4904 SourceManager &SM = FD->getASTContext().getSourceManager();
4905 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4906 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4907 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4908 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4909 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4910 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4911}
4912
4913
4914CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4915 unsigned PieceIndex) {
4916 RefNamePieces Pieces;
4917
4918 switch (C.kind) {
4919 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004920 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004921 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4922 E->getQualifierLoc().getSourceRange());
4923 break;
4924
4925 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004926 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004927 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4928 E->getQualifierLoc().getSourceRange(),
4929 E->getOptionalExplicitTemplateArgs());
4930 break;
4931
4932 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004933 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004934 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004935 const Expr *Callee = OCE->getCallee();
4936 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004937 Callee = ICE->getSubExpr();
4938
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004939 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004940 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4941 DRE->getQualifierLoc().getSourceRange());
4942 }
4943 break;
4944
4945 default:
4946 break;
4947 }
4948
4949 if (Pieces.empty()) {
4950 if (PieceIndex == 0)
4951 return clang_getCursorExtent(C);
4952 } else if (PieceIndex < Pieces.size()) {
4953 SourceRange R = Pieces[PieceIndex];
4954 if (R.isValid())
4955 return cxloc::translateSourceRange(getCursorContext(C), R);
4956 }
4957
4958 return clang_getNullRange();
4959}
4960
4961void clang_enableStackTraces(void) {
4962 llvm::sys::PrintStackTraceOnErrorSignal();
4963}
4964
4965void clang_executeOnThread(void (*fn)(void*), void *user_data,
4966 unsigned stack_size) {
4967 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4968}
4969
4970} // end: extern "C"
4971
4972//===----------------------------------------------------------------------===//
4973// Token-based Operations.
4974//===----------------------------------------------------------------------===//
4975
4976/* CXToken layout:
4977 * int_data[0]: a CXTokenKind
4978 * int_data[1]: starting token location
4979 * int_data[2]: token length
4980 * int_data[3]: reserved
4981 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4982 * otherwise unused.
4983 */
4984extern "C" {
4985
4986CXTokenKind clang_getTokenKind(CXToken CXTok) {
4987 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4988}
4989
4990CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4991 switch (clang_getTokenKind(CXTok)) {
4992 case CXToken_Identifier:
4993 case CXToken_Keyword:
4994 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004995 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004996 ->getNameStart());
4997
4998 case CXToken_Literal: {
4999 // We have stashed the starting pointer in the ptr_data field. Use it.
5000 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005001 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005002 }
5003
5004 case CXToken_Punctuation:
5005 case CXToken_Comment:
5006 break;
5007 }
5008
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005009 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005010 LOG_BAD_TU(TU);
5011 return cxstring::createEmpty();
5012 }
5013
Guy Benyei11169dd2012-12-18 14:30:41 +00005014 // We have to find the starting buffer pointer the hard way, by
5015 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005016 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005017 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005018 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005019
5020 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5021 std::pair<FileID, unsigned> LocInfo
5022 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5023 bool Invalid = false;
5024 StringRef Buffer
5025 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5026 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005027 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005028
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005029 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005030}
5031
5032CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005033 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005034 LOG_BAD_TU(TU);
5035 return clang_getNullLocation();
5036 }
5037
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005038 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005039 if (!CXXUnit)
5040 return clang_getNullLocation();
5041
5042 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5043 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5044}
5045
5046CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005047 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005048 LOG_BAD_TU(TU);
5049 return clang_getNullRange();
5050 }
5051
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005052 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005053 if (!CXXUnit)
5054 return clang_getNullRange();
5055
5056 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5057 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5058}
5059
5060static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5061 SmallVectorImpl<CXToken> &CXTokens) {
5062 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5063 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005064 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005065 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005066 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005067
5068 // Cannot tokenize across files.
5069 if (BeginLocInfo.first != EndLocInfo.first)
5070 return;
5071
5072 // Create a lexer
5073 bool Invalid = false;
5074 StringRef Buffer
5075 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5076 if (Invalid)
5077 return;
5078
5079 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5080 CXXUnit->getASTContext().getLangOpts(),
5081 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5082 Lex.SetCommentRetentionState(true);
5083
5084 // Lex tokens until we hit the end of the range.
5085 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5086 Token Tok;
5087 bool previousWasAt = false;
5088 do {
5089 // Lex the next token
5090 Lex.LexFromRawLexer(Tok);
5091 if (Tok.is(tok::eof))
5092 break;
5093
5094 // Initialize the CXToken.
5095 CXToken CXTok;
5096
5097 // - Common fields
5098 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5099 CXTok.int_data[2] = Tok.getLength();
5100 CXTok.int_data[3] = 0;
5101
5102 // - Kind-specific fields
5103 if (Tok.isLiteral()) {
5104 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005105 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005106 } else if (Tok.is(tok::raw_identifier)) {
5107 // Lookup the identifier to determine whether we have a keyword.
5108 IdentifierInfo *II
5109 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5110
5111 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5112 CXTok.int_data[0] = CXToken_Keyword;
5113 }
5114 else {
5115 CXTok.int_data[0] = Tok.is(tok::identifier)
5116 ? CXToken_Identifier
5117 : CXToken_Keyword;
5118 }
5119 CXTok.ptr_data = II;
5120 } else if (Tok.is(tok::comment)) {
5121 CXTok.int_data[0] = CXToken_Comment;
5122 CXTok.ptr_data = 0;
5123 } else {
5124 CXTok.int_data[0] = CXToken_Punctuation;
5125 CXTok.ptr_data = 0;
5126 }
5127 CXTokens.push_back(CXTok);
5128 previousWasAt = Tok.is(tok::at);
5129 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5130}
5131
5132void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5133 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005134 LOG_FUNC_SECTION {
5135 *Log << TU << ' ' << Range;
5136 }
5137
Guy Benyei11169dd2012-12-18 14:30:41 +00005138 if (Tokens)
5139 *Tokens = 0;
5140 if (NumTokens)
5141 *NumTokens = 0;
5142
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005143 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005144 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005145 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005146 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005147
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005148 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005149 if (!CXXUnit || !Tokens || !NumTokens)
5150 return;
5151
5152 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5153
5154 SourceRange R = cxloc::translateCXSourceRange(Range);
5155 if (R.isInvalid())
5156 return;
5157
5158 SmallVector<CXToken, 32> CXTokens;
5159 getTokens(CXXUnit, R, CXTokens);
5160
5161 if (CXTokens.empty())
5162 return;
5163
5164 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5165 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5166 *NumTokens = CXTokens.size();
5167}
5168
5169void clang_disposeTokens(CXTranslationUnit TU,
5170 CXToken *Tokens, unsigned NumTokens) {
5171 free(Tokens);
5172}
5173
5174} // end: extern "C"
5175
5176//===----------------------------------------------------------------------===//
5177// Token annotation APIs.
5178//===----------------------------------------------------------------------===//
5179
Guy Benyei11169dd2012-12-18 14:30:41 +00005180static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5181 CXCursor parent,
5182 CXClientData client_data);
5183static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5184 CXClientData client_data);
5185
5186namespace {
5187class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005188 CXToken *Tokens;
5189 CXCursor *Cursors;
5190 unsigned NumTokens;
5191 unsigned TokIdx;
5192 unsigned PreprocessingTokIdx;
5193 CursorVisitor AnnotateVis;
5194 SourceManager &SrcMgr;
5195 bool HasContextSensitiveKeywords;
5196
5197 struct PostChildrenInfo {
5198 CXCursor Cursor;
5199 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005200 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005201 unsigned BeforeChildrenTokenIdx;
5202 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005203 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005204
5205 CXToken &getTok(unsigned Idx) {
5206 assert(Idx < NumTokens);
5207 return Tokens[Idx];
5208 }
5209 const CXToken &getTok(unsigned Idx) const {
5210 assert(Idx < NumTokens);
5211 return Tokens[Idx];
5212 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005213 bool MoreTokens() const { return TokIdx < NumTokens; }
5214 unsigned NextToken() const { return TokIdx; }
5215 void AdvanceToken() { ++TokIdx; }
5216 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005217 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 }
5219 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005220 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005221 }
5222 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005223 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 }
5225
5226 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005227 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 SourceRange);
5229
5230public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005231 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005232 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005233 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005234 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005235 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005236 AnnotateTokensVisitor, this,
5237 /*VisitPreprocessorLast=*/true,
5238 /*VisitIncludedEntities=*/false,
5239 RegionOfInterest,
5240 /*VisitDeclsOnly=*/false,
5241 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005242 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005243 HasContextSensitiveKeywords(false) { }
5244
5245 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5246 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5247 bool postVisitChildren(CXCursor cursor);
5248 void AnnotateTokens();
5249
5250 /// \brief Determine whether the annotator saw any cursors that have
5251 /// context-sensitive keywords.
5252 bool hasContextSensitiveKeywords() const {
5253 return HasContextSensitiveKeywords;
5254 }
5255
5256 ~AnnotateTokensWorker() {
5257 assert(PostChildrenInfos.empty());
5258 }
5259};
5260}
5261
5262void AnnotateTokensWorker::AnnotateTokens() {
5263 // Walk the AST within the region of interest, annotating tokens
5264 // along the way.
5265 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005266}
Guy Benyei11169dd2012-12-18 14:30:41 +00005267
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005268static inline void updateCursorAnnotation(CXCursor &Cursor,
5269 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005270 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005271 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005272 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005273}
5274
5275/// \brief It annotates and advances tokens with a cursor until the comparison
5276//// between the cursor location and the source range is the same as
5277/// \arg compResult.
5278///
5279/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5280/// Pass RangeOverlap to annotate tokens inside a range.
5281void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5282 RangeComparisonResult compResult,
5283 SourceRange range) {
5284 while (MoreTokens()) {
5285 const unsigned I = NextToken();
5286 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005287 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5288 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005289
5290 SourceLocation TokLoc = GetTokenLoc(I);
5291 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005292 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005293 AdvanceToken();
5294 continue;
5295 }
5296 break;
5297 }
5298}
5299
5300/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005301/// \returns true if it advanced beyond all macro tokens, false otherwise.
5302bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005303 CXCursor updateC,
5304 RangeComparisonResult compResult,
5305 SourceRange range) {
5306 assert(MoreTokens());
5307 assert(isFunctionMacroToken(NextToken()) &&
5308 "Should be called only for macro arg tokens");
5309
5310 // This works differently than annotateAndAdvanceTokens; because expanded
5311 // macro arguments can have arbitrary translation-unit source order, we do not
5312 // advance the token index one by one until a token fails the range test.
5313 // We only advance once past all of the macro arg tokens if all of them
5314 // pass the range test. If one of them fails we keep the token index pointing
5315 // at the start of the macro arg tokens so that the failing token will be
5316 // annotated by a subsequent annotation try.
5317
5318 bool atLeastOneCompFail = false;
5319
5320 unsigned I = NextToken();
5321 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5322 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5323 if (TokLoc.isFileID())
5324 continue; // not macro arg token, it's parens or comma.
5325 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5326 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5327 Cursors[I] = updateC;
5328 } else
5329 atLeastOneCompFail = true;
5330 }
5331
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005332 if (atLeastOneCompFail)
5333 return false;
5334
5335 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5336 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005337}
5338
5339enum CXChildVisitResult
5340AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005341 SourceRange cursorRange = getRawCursorExtent(cursor);
5342 if (cursorRange.isInvalid())
5343 return CXChildVisit_Recurse;
5344
5345 if (!HasContextSensitiveKeywords) {
5346 // Objective-C properties can have context-sensitive keywords.
5347 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005348 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005349 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5350 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5351 }
5352 // Objective-C methods can have context-sensitive keywords.
5353 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5354 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005355 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005356 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5357 if (Method->getObjCDeclQualifier())
5358 HasContextSensitiveKeywords = true;
5359 else {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005360 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5361 PEnd = Method->param_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00005362 P != PEnd; ++P) {
5363 if ((*P)->getObjCDeclQualifier()) {
5364 HasContextSensitiveKeywords = true;
5365 break;
5366 }
5367 }
5368 }
5369 }
5370 }
5371 // C++ methods can have context-sensitive keywords.
5372 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005373 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005374 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5375 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5376 HasContextSensitiveKeywords = true;
5377 }
5378 }
5379 // C++ classes can have context-sensitive keywords.
5380 else if (cursor.kind == CXCursor_StructDecl ||
5381 cursor.kind == CXCursor_ClassDecl ||
5382 cursor.kind == CXCursor_ClassTemplate ||
5383 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005384 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005385 if (D->hasAttr<FinalAttr>())
5386 HasContextSensitiveKeywords = true;
5387 }
5388 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005389
5390 // Don't override a property annotation with its getter/setter method.
5391 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5392 parent.kind == CXCursor_ObjCPropertyDecl)
5393 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005394
5395 if (clang_isPreprocessing(cursor.kind)) {
5396 // Items in the preprocessing record are kept separate from items in
5397 // declarations, so we keep a separate token index.
5398 unsigned SavedTokIdx = TokIdx;
5399 TokIdx = PreprocessingTokIdx;
5400
5401 // Skip tokens up until we catch up to the beginning of the preprocessing
5402 // entry.
5403 while (MoreTokens()) {
5404 const unsigned I = NextToken();
5405 SourceLocation TokLoc = GetTokenLoc(I);
5406 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5407 case RangeBefore:
5408 AdvanceToken();
5409 continue;
5410 case RangeAfter:
5411 case RangeOverlap:
5412 break;
5413 }
5414 break;
5415 }
5416
5417 // Look at all of the tokens within this range.
5418 while (MoreTokens()) {
5419 const unsigned I = NextToken();
5420 SourceLocation TokLoc = GetTokenLoc(I);
5421 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5422 case RangeBefore:
5423 llvm_unreachable("Infeasible");
5424 case RangeAfter:
5425 break;
5426 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005427 // For macro expansions, just note where the beginning of the macro
5428 // expansion occurs.
5429 if (cursor.kind == CXCursor_MacroExpansion) {
5430 if (TokLoc == cursorRange.getBegin())
5431 Cursors[I] = cursor;
5432 AdvanceToken();
5433 break;
5434 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005435 // We may have already annotated macro names inside macro definitions.
5436 if (Cursors[I].kind != CXCursor_MacroExpansion)
5437 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005438 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005439 continue;
5440 }
5441 break;
5442 }
5443
5444 // Save the preprocessing token index; restore the non-preprocessing
5445 // token index.
5446 PreprocessingTokIdx = TokIdx;
5447 TokIdx = SavedTokIdx;
5448 return CXChildVisit_Recurse;
5449 }
5450
5451 if (cursorRange.isInvalid())
5452 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005453
5454 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005455 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005456 const enum CXCursorKind K = clang_getCursorKind(parent);
5457 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005458 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5459 // Attributes are annotated out-of-order, skip tokens until we reach it.
5460 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005461 ? clang_getNullCursor() : parent;
5462
5463 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5464
5465 // Avoid having the cursor of an expression "overwrite" the annotation of the
5466 // variable declaration that it belongs to.
5467 // This can happen for C++ constructor expressions whose range generally
5468 // include the variable declaration, e.g.:
5469 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005470 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005471 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005472 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005473 const unsigned I = NextToken();
5474 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5475 E->getLocStart() == D->getLocation() &&
5476 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005477 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005478 AdvanceToken();
5479 }
5480 }
5481 }
5482
5483 // Before recursing into the children keep some state that we are going
5484 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5485 // extra work after the child nodes are visited.
5486 // Note that we don't call VisitChildren here to avoid traversing statements
5487 // code-recursively which can blow the stack.
5488
5489 PostChildrenInfo Info;
5490 Info.Cursor = cursor;
5491 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005492 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005493 Info.BeforeChildrenTokenIdx = NextToken();
5494 PostChildrenInfos.push_back(Info);
5495
5496 return CXChildVisit_Recurse;
5497}
5498
5499bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5500 if (PostChildrenInfos.empty())
5501 return false;
5502 const PostChildrenInfo &Info = PostChildrenInfos.back();
5503 if (!clang_equalCursors(Info.Cursor, cursor))
5504 return false;
5505
5506 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5507 const unsigned AfterChildren = NextToken();
5508 SourceRange cursorRange = Info.CursorRange;
5509
5510 // Scan the tokens that are at the end of the cursor, but are not captured
5511 // but the child cursors.
5512 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5513
5514 // Scan the tokens that are at the beginning of the cursor, but are not
5515 // capture by the child cursors.
5516 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5517 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5518 break;
5519
5520 Cursors[I] = cursor;
5521 }
5522
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005523 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5524 // encountered the attribute cursor.
5525 if (clang_isAttribute(cursor.kind))
5526 TokIdx = Info.BeforeReachingCursorIdx;
5527
Guy Benyei11169dd2012-12-18 14:30:41 +00005528 PostChildrenInfos.pop_back();
5529 return false;
5530}
5531
5532static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5533 CXCursor parent,
5534 CXClientData client_data) {
5535 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5536}
5537
5538static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5539 CXClientData client_data) {
5540 return static_cast<AnnotateTokensWorker*>(client_data)->
5541 postVisitChildren(cursor);
5542}
5543
5544namespace {
5545
5546/// \brief Uses the macro expansions in the preprocessing record to find
5547/// and mark tokens that are macro arguments. This info is used by the
5548/// AnnotateTokensWorker.
5549class MarkMacroArgTokensVisitor {
5550 SourceManager &SM;
5551 CXToken *Tokens;
5552 unsigned NumTokens;
5553 unsigned CurIdx;
5554
5555public:
5556 MarkMacroArgTokensVisitor(SourceManager &SM,
5557 CXToken *tokens, unsigned numTokens)
5558 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5559
5560 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5561 if (cursor.kind != CXCursor_MacroExpansion)
5562 return CXChildVisit_Continue;
5563
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005564 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005565 if (macroRange.getBegin() == macroRange.getEnd())
5566 return CXChildVisit_Continue; // it's not a function macro.
5567
5568 for (; CurIdx < NumTokens; ++CurIdx) {
5569 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5570 macroRange.getBegin()))
5571 break;
5572 }
5573
5574 if (CurIdx == NumTokens)
5575 return CXChildVisit_Break;
5576
5577 for (; CurIdx < NumTokens; ++CurIdx) {
5578 SourceLocation tokLoc = getTokenLoc(CurIdx);
5579 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5580 break;
5581
5582 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5583 }
5584
5585 if (CurIdx == NumTokens)
5586 return CXChildVisit_Break;
5587
5588 return CXChildVisit_Continue;
5589 }
5590
5591private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005592 CXToken &getTok(unsigned Idx) {
5593 assert(Idx < NumTokens);
5594 return Tokens[Idx];
5595 }
5596 const CXToken &getTok(unsigned Idx) const {
5597 assert(Idx < NumTokens);
5598 return Tokens[Idx];
5599 }
5600
Guy Benyei11169dd2012-12-18 14:30:41 +00005601 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005602 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005603 }
5604
5605 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5606 // The third field is reserved and currently not used. Use it here
5607 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005608 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005609 }
5610};
5611
5612} // end anonymous namespace
5613
5614static CXChildVisitResult
5615MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5616 CXClientData client_data) {
5617 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5618 parent);
5619}
5620
5621namespace {
5622 struct clang_annotateTokens_Data {
5623 CXTranslationUnit TU;
5624 ASTUnit *CXXUnit;
5625 CXToken *Tokens;
5626 unsigned NumTokens;
5627 CXCursor *Cursors;
5628 };
5629}
5630
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005631/// \brief Used by \c annotatePreprocessorTokens.
5632/// \returns true if lexing was finished, false otherwise.
5633static bool lexNext(Lexer &Lex, Token &Tok,
5634 unsigned &NextIdx, unsigned NumTokens) {
5635 if (NextIdx >= NumTokens)
5636 return true;
5637
5638 ++NextIdx;
5639 Lex.LexFromRawLexer(Tok);
5640 if (Tok.is(tok::eof))
5641 return true;
5642
5643 return false;
5644}
5645
Guy Benyei11169dd2012-12-18 14:30:41 +00005646static void annotatePreprocessorTokens(CXTranslationUnit TU,
5647 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005648 CXCursor *Cursors,
5649 CXToken *Tokens,
5650 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005651 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005652
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005653 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005654 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5655 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005656 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005657 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005658 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005659
5660 if (BeginLocInfo.first != EndLocInfo.first)
5661 return;
5662
5663 StringRef Buffer;
5664 bool Invalid = false;
5665 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5666 if (Buffer.empty() || Invalid)
5667 return;
5668
5669 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5670 CXXUnit->getASTContext().getLangOpts(),
5671 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5672 Buffer.end());
5673 Lex.SetCommentRetentionState(true);
5674
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005675 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005676 // Lex tokens in raw mode until we hit the end of the range, to avoid
5677 // entering #includes or expanding macros.
5678 while (true) {
5679 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005680 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5681 break;
5682 unsigned TokIdx = NextIdx-1;
5683 assert(Tok.getLocation() ==
5684 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005685
5686 reprocess:
5687 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005688 // We have found a preprocessing directive. Annotate the tokens
5689 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005690 //
5691 // FIXME: Some simple tests here could identify macro definitions and
5692 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005693
5694 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005695 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5696 break;
5697
5698 MacroInfo *MI = 0;
5699 if (Tok.is(tok::raw_identifier) &&
5700 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5701 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5702 break;
5703
5704 if (Tok.is(tok::raw_identifier)) {
5705 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5706 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5707 SourceLocation MappedTokLoc =
5708 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5709 MI = getMacroInfo(II, MappedTokLoc, TU);
5710 }
5711 }
5712
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005713 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005714 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005715 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5716 finished = true;
5717 break;
5718 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005719 // If we are in a macro definition, check if the token was ever a
5720 // macro name and annotate it if that's the case.
5721 if (MI) {
5722 SourceLocation SaveLoc = Tok.getLocation();
5723 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5724 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5725 Tok.setLocation(SaveLoc);
5726 if (MacroDef)
5727 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5728 Tok.getLocation(), TU);
5729 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005730 } while (!Tok.isAtStartOfLine());
5731
5732 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5733 assert(TokIdx <= LastIdx);
5734 SourceLocation EndLoc =
5735 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5736 CXCursor Cursor =
5737 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5738
5739 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005740 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005741
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005742 if (finished)
5743 break;
5744 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005745 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005746 }
5747}
5748
5749// This gets run a separate thread to avoid stack blowout.
5750static void clang_annotateTokensImpl(void *UserData) {
5751 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5752 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5753 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5754 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5755 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5756
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005757 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005758 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5759 setThreadBackgroundPriority();
5760
5761 // Determine the region of interest, which contains all of the tokens.
5762 SourceRange RegionOfInterest;
5763 RegionOfInterest.setBegin(
5764 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5765 RegionOfInterest.setEnd(
5766 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5767 Tokens[NumTokens-1])));
5768
Guy Benyei11169dd2012-12-18 14:30:41 +00005769 // Relex the tokens within the source range to look for preprocessing
5770 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005771 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005772
5773 // If begin location points inside a macro argument, set it to the expansion
5774 // location so we can have the full context when annotating semantically.
5775 {
5776 SourceManager &SM = CXXUnit->getSourceManager();
5777 SourceLocation Loc =
5778 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5779 if (Loc.isMacroID())
5780 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5781 }
5782
Guy Benyei11169dd2012-12-18 14:30:41 +00005783 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5784 // Search and mark tokens that are macro argument expansions.
5785 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5786 Tokens, NumTokens);
5787 CursorVisitor MacroArgMarker(TU,
5788 MarkMacroArgTokensVisitorDelegate, &Visitor,
5789 /*VisitPreprocessorLast=*/true,
5790 /*VisitIncludedEntities=*/false,
5791 RegionOfInterest);
5792 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5793 }
5794
5795 // Annotate all of the source locations in the region of interest that map to
5796 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005797 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005798
5799 // FIXME: We use a ridiculous stack size here because the data-recursion
5800 // algorithm uses a large stack frame than the non-data recursive version,
5801 // and AnnotationTokensWorker currently transforms the data-recursion
5802 // algorithm back into a traditional recursion by explicitly calling
5803 // VisitChildren(). We will need to remove this explicit recursive call.
5804 W.AnnotateTokens();
5805
5806 // If we ran into any entities that involve context-sensitive keywords,
5807 // take another pass through the tokens to mark them as such.
5808 if (W.hasContextSensitiveKeywords()) {
5809 for (unsigned I = 0; I != NumTokens; ++I) {
5810 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5811 continue;
5812
5813 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5814 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005815 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005816 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5817 if (Property->getPropertyAttributesAsWritten() != 0 &&
5818 llvm::StringSwitch<bool>(II->getName())
5819 .Case("readonly", true)
5820 .Case("assign", true)
5821 .Case("unsafe_unretained", true)
5822 .Case("readwrite", true)
5823 .Case("retain", true)
5824 .Case("copy", true)
5825 .Case("nonatomic", true)
5826 .Case("atomic", true)
5827 .Case("getter", true)
5828 .Case("setter", true)
5829 .Case("strong", true)
5830 .Case("weak", true)
5831 .Default(false))
5832 Tokens[I].int_data[0] = CXToken_Keyword;
5833 }
5834 continue;
5835 }
5836
5837 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5838 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5839 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5840 if (llvm::StringSwitch<bool>(II->getName())
5841 .Case("in", true)
5842 .Case("out", true)
5843 .Case("inout", true)
5844 .Case("oneway", true)
5845 .Case("bycopy", true)
5846 .Case("byref", true)
5847 .Default(false))
5848 Tokens[I].int_data[0] = CXToken_Keyword;
5849 continue;
5850 }
5851
5852 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5853 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5854 Tokens[I].int_data[0] = CXToken_Keyword;
5855 continue;
5856 }
5857 }
5858 }
5859}
5860
5861extern "C" {
5862
5863void clang_annotateTokens(CXTranslationUnit TU,
5864 CXToken *Tokens, unsigned NumTokens,
5865 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005866 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005867 LOG_BAD_TU(TU);
5868 return;
5869 }
5870 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005871 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005872 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005873 }
5874
5875 LOG_FUNC_SECTION {
5876 *Log << TU << ' ';
5877 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5878 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5879 *Log << clang_getRange(bloc, eloc);
5880 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005881
5882 // Any token we don't specifically annotate will have a NULL cursor.
5883 CXCursor C = clang_getNullCursor();
5884 for (unsigned I = 0; I != NumTokens; ++I)
5885 Cursors[I] = C;
5886
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005887 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005888 if (!CXXUnit)
5889 return;
5890
5891 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5892
5893 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5894 llvm::CrashRecoveryContext CRC;
5895 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5896 GetSafetyThreadStackSize() * 2)) {
5897 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5898 }
5899}
5900
5901} // end: extern "C"
5902
5903//===----------------------------------------------------------------------===//
5904// Operations for querying linkage of a cursor.
5905//===----------------------------------------------------------------------===//
5906
5907extern "C" {
5908CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5909 if (!clang_isDeclaration(cursor.kind))
5910 return CXLinkage_Invalid;
5911
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005912 const Decl *D = cxcursor::getCursorDecl(cursor);
5913 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005914 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005915 case NoLinkage:
5916 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005917 case InternalLinkage: return CXLinkage_Internal;
5918 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5919 case ExternalLinkage: return CXLinkage_External;
5920 };
5921
5922 return CXLinkage_Invalid;
5923}
5924} // end: extern "C"
5925
5926//===----------------------------------------------------------------------===//
5927// Operations for querying language of a cursor.
5928//===----------------------------------------------------------------------===//
5929
5930static CXLanguageKind getDeclLanguage(const Decl *D) {
5931 if (!D)
5932 return CXLanguage_C;
5933
5934 switch (D->getKind()) {
5935 default:
5936 break;
5937 case Decl::ImplicitParam:
5938 case Decl::ObjCAtDefsField:
5939 case Decl::ObjCCategory:
5940 case Decl::ObjCCategoryImpl:
5941 case Decl::ObjCCompatibleAlias:
5942 case Decl::ObjCImplementation:
5943 case Decl::ObjCInterface:
5944 case Decl::ObjCIvar:
5945 case Decl::ObjCMethod:
5946 case Decl::ObjCProperty:
5947 case Decl::ObjCPropertyImpl:
5948 case Decl::ObjCProtocol:
5949 return CXLanguage_ObjC;
5950 case Decl::CXXConstructor:
5951 case Decl::CXXConversion:
5952 case Decl::CXXDestructor:
5953 case Decl::CXXMethod:
5954 case Decl::CXXRecord:
5955 case Decl::ClassTemplate:
5956 case Decl::ClassTemplatePartialSpecialization:
5957 case Decl::ClassTemplateSpecialization:
5958 case Decl::Friend:
5959 case Decl::FriendTemplate:
5960 case Decl::FunctionTemplate:
5961 case Decl::LinkageSpec:
5962 case Decl::Namespace:
5963 case Decl::NamespaceAlias:
5964 case Decl::NonTypeTemplateParm:
5965 case Decl::StaticAssert:
5966 case Decl::TemplateTemplateParm:
5967 case Decl::TemplateTypeParm:
5968 case Decl::UnresolvedUsingTypename:
5969 case Decl::UnresolvedUsingValue:
5970 case Decl::Using:
5971 case Decl::UsingDirective:
5972 case Decl::UsingShadow:
5973 return CXLanguage_CPlusPlus;
5974 }
5975
5976 return CXLanguage_C;
5977}
5978
5979extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005980
5981static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5982 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5983 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005984
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005985 switch (D->getAvailability()) {
5986 case AR_Available:
5987 case AR_NotYetIntroduced:
5988 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005989 return getCursorAvailabilityForDecl(
5990 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005991 return CXAvailability_Available;
5992
5993 case AR_Deprecated:
5994 return CXAvailability_Deprecated;
5995
5996 case AR_Unavailable:
5997 return CXAvailability_NotAvailable;
5998 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005999
6000 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006001}
6002
Guy Benyei11169dd2012-12-18 14:30:41 +00006003enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6004 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006005 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6006 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006007
6008 return CXAvailability_Available;
6009}
6010
6011static CXVersion convertVersion(VersionTuple In) {
6012 CXVersion Out = { -1, -1, -1 };
6013 if (In.empty())
6014 return Out;
6015
6016 Out.Major = In.getMajor();
6017
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006018 Optional<unsigned> Minor = In.getMinor();
6019 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006020 Out.Minor = *Minor;
6021 else
6022 return Out;
6023
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006024 Optional<unsigned> Subminor = In.getSubminor();
6025 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006026 Out.Subminor = *Subminor;
6027
6028 return Out;
6029}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006030
6031static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6032 int *always_deprecated,
6033 CXString *deprecated_message,
6034 int *always_unavailable,
6035 CXString *unavailable_message,
6036 CXPlatformAvailability *availability,
6037 int availability_size) {
6038 bool HadAvailAttr = false;
6039 int N = 0;
6040 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
6041 ++A) {
6042 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
6043 HadAvailAttr = true;
6044 if (always_deprecated)
6045 *always_deprecated = 1;
6046 if (deprecated_message)
6047 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
6048 continue;
6049 }
6050
6051 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
6052 HadAvailAttr = true;
6053 if (always_unavailable)
6054 *always_unavailable = 1;
6055 if (unavailable_message) {
6056 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6057 }
6058 continue;
6059 }
6060
6061 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
6062 HadAvailAttr = true;
6063 if (N < availability_size) {
6064 availability[N].Platform
6065 = cxstring::createDup(Avail->getPlatform()->getName());
6066 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6067 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6068 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6069 availability[N].Unavailable = Avail->getUnavailable();
6070 availability[N].Message = cxstring::createDup(Avail->getMessage());
6071 }
6072 ++N;
6073 }
6074 }
6075
6076 if (!HadAvailAttr)
6077 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6078 return getCursorPlatformAvailabilityForDecl(
6079 cast<Decl>(EnumConst->getDeclContext()),
6080 always_deprecated,
6081 deprecated_message,
6082 always_unavailable,
6083 unavailable_message,
6084 availability,
6085 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006086
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006087 return N;
6088}
6089
Guy Benyei11169dd2012-12-18 14:30:41 +00006090int clang_getCursorPlatformAvailability(CXCursor cursor,
6091 int *always_deprecated,
6092 CXString *deprecated_message,
6093 int *always_unavailable,
6094 CXString *unavailable_message,
6095 CXPlatformAvailability *availability,
6096 int availability_size) {
6097 if (always_deprecated)
6098 *always_deprecated = 0;
6099 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006100 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006101 if (always_unavailable)
6102 *always_unavailable = 0;
6103 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006104 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006105
Guy Benyei11169dd2012-12-18 14:30:41 +00006106 if (!clang_isDeclaration(cursor.kind))
6107 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006108
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006109 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006110 if (!D)
6111 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006112
6113 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6114 deprecated_message,
6115 always_unavailable,
6116 unavailable_message,
6117 availability,
6118 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006119}
6120
6121void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6122 clang_disposeString(availability->Platform);
6123 clang_disposeString(availability->Message);
6124}
6125
6126CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6127 if (clang_isDeclaration(cursor.kind))
6128 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6129
6130 return CXLanguage_Invalid;
6131}
6132
6133 /// \brief If the given cursor is the "templated" declaration
6134 /// descibing a class or function template, return the class or
6135 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006136static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006137 if (!D)
6138 return 0;
6139
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006140 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006141 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6142 return FunTmpl;
6143
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006144 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006145 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6146 return ClassTmpl;
6147
6148 return D;
6149}
6150
6151CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6152 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006153 if (const Decl *D = getCursorDecl(cursor)) {
6154 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006155 if (!DC)
6156 return clang_getNullCursor();
6157
6158 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6159 getCursorTU(cursor));
6160 }
6161 }
6162
6163 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006164 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006165 return MakeCXCursor(D, getCursorTU(cursor));
6166 }
6167
6168 return clang_getNullCursor();
6169}
6170
6171CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6172 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006173 if (const Decl *D = getCursorDecl(cursor)) {
6174 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006175 if (!DC)
6176 return clang_getNullCursor();
6177
6178 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6179 getCursorTU(cursor));
6180 }
6181 }
6182
6183 // FIXME: Note that we can't easily compute the lexical context of a
6184 // statement or expression, so we return nothing.
6185 return clang_getNullCursor();
6186}
6187
6188CXFile clang_getIncludedFile(CXCursor cursor) {
6189 if (cursor.kind != CXCursor_InclusionDirective)
6190 return 0;
6191
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006192 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006193 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006194}
6195
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006196unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6197 if (C.kind != CXCursor_ObjCPropertyDecl)
6198 return CXObjCPropertyAttr_noattr;
6199
6200 unsigned Result = CXObjCPropertyAttr_noattr;
6201 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6202 ObjCPropertyDecl::PropertyAttributeKind Attr =
6203 PD->getPropertyAttributesAsWritten();
6204
6205#define SET_CXOBJCPROP_ATTR(A) \
6206 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6207 Result |= CXObjCPropertyAttr_##A
6208 SET_CXOBJCPROP_ATTR(readonly);
6209 SET_CXOBJCPROP_ATTR(getter);
6210 SET_CXOBJCPROP_ATTR(assign);
6211 SET_CXOBJCPROP_ATTR(readwrite);
6212 SET_CXOBJCPROP_ATTR(retain);
6213 SET_CXOBJCPROP_ATTR(copy);
6214 SET_CXOBJCPROP_ATTR(nonatomic);
6215 SET_CXOBJCPROP_ATTR(setter);
6216 SET_CXOBJCPROP_ATTR(atomic);
6217 SET_CXOBJCPROP_ATTR(weak);
6218 SET_CXOBJCPROP_ATTR(strong);
6219 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6220#undef SET_CXOBJCPROP_ATTR
6221
6222 return Result;
6223}
6224
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006225unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6226 if (!clang_isDeclaration(C.kind))
6227 return CXObjCDeclQualifier_None;
6228
6229 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6230 const Decl *D = getCursorDecl(C);
6231 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6232 QT = MD->getObjCDeclQualifier();
6233 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6234 QT = PD->getObjCDeclQualifier();
6235 if (QT == Decl::OBJC_TQ_None)
6236 return CXObjCDeclQualifier_None;
6237
6238 unsigned Result = CXObjCDeclQualifier_None;
6239 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6240 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6241 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6242 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6243 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6244 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6245
6246 return Result;
6247}
6248
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006249unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6250 if (!clang_isDeclaration(C.kind))
6251 return 0;
6252
6253 const Decl *D = getCursorDecl(C);
6254 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6255 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6256 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6257 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6258
6259 return 0;
6260}
6261
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006262unsigned clang_Cursor_isVariadic(CXCursor C) {
6263 if (!clang_isDeclaration(C.kind))
6264 return 0;
6265
6266 const Decl *D = getCursorDecl(C);
6267 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6268 return FD->isVariadic();
6269 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6270 return MD->isVariadic();
6271
6272 return 0;
6273}
6274
Guy Benyei11169dd2012-12-18 14:30:41 +00006275CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6276 if (!clang_isDeclaration(C.kind))
6277 return clang_getNullRange();
6278
6279 const Decl *D = getCursorDecl(C);
6280 ASTContext &Context = getCursorContext(C);
6281 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6282 if (!RC)
6283 return clang_getNullRange();
6284
6285 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6286}
6287
6288CXString clang_Cursor_getRawCommentText(CXCursor C) {
6289 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006290 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006291
6292 const Decl *D = getCursorDecl(C);
6293 ASTContext &Context = getCursorContext(C);
6294 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6295 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6296 StringRef();
6297
6298 // Don't duplicate the string because RawText points directly into source
6299 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006300 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006301}
6302
6303CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6304 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006305 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006306
6307 const Decl *D = getCursorDecl(C);
6308 const ASTContext &Context = getCursorContext(C);
6309 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6310
6311 if (RC) {
6312 StringRef BriefText = RC->getBriefText(Context);
6313
6314 // Don't duplicate the string because RawComment ensures that this memory
6315 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006316 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006317 }
6318
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006319 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006320}
6321
6322CXComment clang_Cursor_getParsedComment(CXCursor C) {
6323 if (!clang_isDeclaration(C.kind))
6324 return cxcomment::createCXComment(NULL, NULL);
6325
6326 const Decl *D = getCursorDecl(C);
6327 const ASTContext &Context = getCursorContext(C);
6328 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6329
6330 return cxcomment::createCXComment(FC, getCursorTU(C));
6331}
6332
6333CXModule clang_Cursor_getModule(CXCursor C) {
6334 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006335 if (const ImportDecl *ImportD =
6336 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006337 return ImportD->getImportedModule();
6338 }
6339
6340 return 0;
6341}
6342
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006343CXFile clang_Module_getASTFile(CXModule CXMod) {
6344 if (!CXMod)
6345 return 0;
6346 Module *Mod = static_cast<Module*>(CXMod);
6347 return const_cast<FileEntry *>(Mod->getASTFile());
6348}
6349
Guy Benyei11169dd2012-12-18 14:30:41 +00006350CXModule clang_Module_getParent(CXModule CXMod) {
6351 if (!CXMod)
6352 return 0;
6353 Module *Mod = static_cast<Module*>(CXMod);
6354 return Mod->Parent;
6355}
6356
6357CXString clang_Module_getName(CXModule CXMod) {
6358 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006359 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006360 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006361 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006362}
6363
6364CXString clang_Module_getFullName(CXModule CXMod) {
6365 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006366 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006367 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006368 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006369}
6370
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006371unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6372 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006373 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006374 LOG_BAD_TU(TU);
6375 return 0;
6376 }
6377 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006378 return 0;
6379 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006380 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6381 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6382 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006383}
6384
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006385CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6386 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006387 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006388 LOG_BAD_TU(TU);
6389 return 0;
6390 }
6391 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006392 return 0;
6393 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006394 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006395
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006396 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6397 if (Index < TopHeaders.size())
6398 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006399
6400 return 0;
6401}
6402
6403} // end: extern "C"
6404
6405//===----------------------------------------------------------------------===//
6406// C++ AST instrospection.
6407//===----------------------------------------------------------------------===//
6408
6409extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006410unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6411 if (!clang_isDeclaration(C.kind))
6412 return 0;
6413
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006414 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006415 const CXXMethodDecl *Method =
6416 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006417 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6418}
6419
Guy Benyei11169dd2012-12-18 14:30:41 +00006420unsigned clang_CXXMethod_isStatic(CXCursor C) {
6421 if (!clang_isDeclaration(C.kind))
6422 return 0;
6423
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006424 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006425 const CXXMethodDecl *Method =
6426 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006427 return (Method && Method->isStatic()) ? 1 : 0;
6428}
6429
6430unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6431 if (!clang_isDeclaration(C.kind))
6432 return 0;
6433
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006434 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006435 const CXXMethodDecl *Method =
6436 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006437 return (Method && Method->isVirtual()) ? 1 : 0;
6438}
6439} // end: extern "C"
6440
6441//===----------------------------------------------------------------------===//
6442// Attribute introspection.
6443//===----------------------------------------------------------------------===//
6444
6445extern "C" {
6446CXType clang_getIBOutletCollectionType(CXCursor C) {
6447 if (C.kind != CXCursor_IBOutletCollectionAttr)
6448 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6449
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006450 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006451 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6452
6453 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6454}
6455} // end: extern "C"
6456
6457//===----------------------------------------------------------------------===//
6458// Inspecting memory usage.
6459//===----------------------------------------------------------------------===//
6460
6461typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6462
6463static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6464 enum CXTUResourceUsageKind k,
6465 unsigned long amount) {
6466 CXTUResourceUsageEntry entry = { k, amount };
6467 entries.push_back(entry);
6468}
6469
6470extern "C" {
6471
6472const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6473 const char *str = "";
6474 switch (kind) {
6475 case CXTUResourceUsage_AST:
6476 str = "ASTContext: expressions, declarations, and types";
6477 break;
6478 case CXTUResourceUsage_Identifiers:
6479 str = "ASTContext: identifiers";
6480 break;
6481 case CXTUResourceUsage_Selectors:
6482 str = "ASTContext: selectors";
6483 break;
6484 case CXTUResourceUsage_GlobalCompletionResults:
6485 str = "Code completion: cached global results";
6486 break;
6487 case CXTUResourceUsage_SourceManagerContentCache:
6488 str = "SourceManager: content cache allocator";
6489 break;
6490 case CXTUResourceUsage_AST_SideTables:
6491 str = "ASTContext: side tables";
6492 break;
6493 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6494 str = "SourceManager: malloc'ed memory buffers";
6495 break;
6496 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6497 str = "SourceManager: mmap'ed memory buffers";
6498 break;
6499 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6500 str = "ExternalASTSource: malloc'ed memory buffers";
6501 break;
6502 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6503 str = "ExternalASTSource: mmap'ed memory buffers";
6504 break;
6505 case CXTUResourceUsage_Preprocessor:
6506 str = "Preprocessor: malloc'ed memory";
6507 break;
6508 case CXTUResourceUsage_PreprocessingRecord:
6509 str = "Preprocessor: PreprocessingRecord";
6510 break;
6511 case CXTUResourceUsage_SourceManager_DataStructures:
6512 str = "SourceManager: data structures and tables";
6513 break;
6514 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6515 str = "Preprocessor: header search tables";
6516 break;
6517 }
6518 return str;
6519}
6520
6521CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006522 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006523 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006524 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6525 return usage;
6526 }
6527
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006528 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006529 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6530 ASTContext &astContext = astUnit->getASTContext();
6531
6532 // How much memory is used by AST nodes and types?
6533 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6534 (unsigned long) astContext.getASTAllocatedMemory());
6535
6536 // How much memory is used by identifiers?
6537 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6538 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6539
6540 // How much memory is used for selectors?
6541 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6542 (unsigned long) astContext.Selectors.getTotalMemory());
6543
6544 // How much memory is used by ASTContext's side tables?
6545 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6546 (unsigned long) astContext.getSideTableAllocatedMemory());
6547
6548 // How much memory is used for caching global code completion results?
6549 unsigned long completionBytes = 0;
6550 if (GlobalCodeCompletionAllocator *completionAllocator =
6551 astUnit->getCachedCompletionAllocator().getPtr()) {
6552 completionBytes = completionAllocator->getTotalMemory();
6553 }
6554 createCXTUResourceUsageEntry(*entries,
6555 CXTUResourceUsage_GlobalCompletionResults,
6556 completionBytes);
6557
6558 // How much memory is being used by SourceManager's content cache?
6559 createCXTUResourceUsageEntry(*entries,
6560 CXTUResourceUsage_SourceManagerContentCache,
6561 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6562
6563 // How much memory is being used by the MemoryBuffer's in SourceManager?
6564 const SourceManager::MemoryBufferSizes &srcBufs =
6565 astUnit->getSourceManager().getMemoryBufferSizes();
6566
6567 createCXTUResourceUsageEntry(*entries,
6568 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6569 (unsigned long) srcBufs.malloc_bytes);
6570 createCXTUResourceUsageEntry(*entries,
6571 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6572 (unsigned long) srcBufs.mmap_bytes);
6573 createCXTUResourceUsageEntry(*entries,
6574 CXTUResourceUsage_SourceManager_DataStructures,
6575 (unsigned long) astContext.getSourceManager()
6576 .getDataStructureSizes());
6577
6578 // How much memory is being used by the ExternalASTSource?
6579 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6580 const ExternalASTSource::MemoryBufferSizes &sizes =
6581 esrc->getMemoryBufferSizes();
6582
6583 createCXTUResourceUsageEntry(*entries,
6584 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6585 (unsigned long) sizes.malloc_bytes);
6586 createCXTUResourceUsageEntry(*entries,
6587 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6588 (unsigned long) sizes.mmap_bytes);
6589 }
6590
6591 // How much memory is being used by the Preprocessor?
6592 Preprocessor &pp = astUnit->getPreprocessor();
6593 createCXTUResourceUsageEntry(*entries,
6594 CXTUResourceUsage_Preprocessor,
6595 pp.getTotalMemory());
6596
6597 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6598 createCXTUResourceUsageEntry(*entries,
6599 CXTUResourceUsage_PreprocessingRecord,
6600 pRec->getTotalMemory());
6601 }
6602
6603 createCXTUResourceUsageEntry(*entries,
6604 CXTUResourceUsage_Preprocessor_HeaderSearch,
6605 pp.getHeaderSearchInfo().getTotalMemory());
6606
6607 CXTUResourceUsage usage = { (void*) entries.get(),
6608 (unsigned) entries->size(),
6609 entries->size() ? &(*entries)[0] : 0 };
6610 entries.take();
6611 return usage;
6612}
6613
6614void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6615 if (usage.data)
6616 delete (MemUsageEntries*) usage.data;
6617}
6618
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006619CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6620 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006621 skipped->count = 0;
6622 skipped->ranges = 0;
6623
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006624 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006625 LOG_BAD_TU(TU);
6626 return skipped;
6627 }
6628
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006629 if (!file)
6630 return skipped;
6631
6632 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6633 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6634 if (!ppRec)
6635 return skipped;
6636
6637 ASTContext &Ctx = astUnit->getASTContext();
6638 SourceManager &sm = Ctx.getSourceManager();
6639 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6640 FileID wantedFileID = sm.translateFile(fileEntry);
6641
6642 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6643 std::vector<SourceRange> wantedRanges;
6644 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6645 i != ei; ++i) {
6646 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6647 wantedRanges.push_back(*i);
6648 }
6649
6650 skipped->count = wantedRanges.size();
6651 skipped->ranges = new CXSourceRange[skipped->count];
6652 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6653 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6654
6655 return skipped;
6656}
6657
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006658void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6659 if (ranges) {
6660 delete[] ranges->ranges;
6661 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006662 }
6663}
6664
Guy Benyei11169dd2012-12-18 14:30:41 +00006665} // end extern "C"
6666
6667void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6668 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6669 for (unsigned I = 0; I != Usage.numEntries; ++I)
6670 fprintf(stderr, " %s: %lu\n",
6671 clang_getTUResourceUsageName(Usage.entries[I].kind),
6672 Usage.entries[I].amount);
6673
6674 clang_disposeCXTUResourceUsage(Usage);
6675}
6676
6677//===----------------------------------------------------------------------===//
6678// Misc. utility functions.
6679//===----------------------------------------------------------------------===//
6680
6681/// Default to using an 8 MB stack size on "safety" threads.
6682static unsigned SafetyStackThreadSize = 8 << 20;
6683
6684namespace clang {
6685
6686bool RunSafely(llvm::CrashRecoveryContext &CRC,
6687 void (*Fn)(void*), void *UserData,
6688 unsigned Size) {
6689 if (!Size)
6690 Size = GetSafetyThreadStackSize();
6691 if (Size)
6692 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6693 return CRC.RunSafely(Fn, UserData);
6694}
6695
6696unsigned GetSafetyThreadStackSize() {
6697 return SafetyStackThreadSize;
6698}
6699
6700void SetSafetyThreadStackSize(unsigned Value) {
6701 SafetyStackThreadSize = Value;
6702}
6703
6704}
6705
6706void clang::setThreadBackgroundPriority() {
6707 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6708 return;
6709
6710 // FIXME: Move to llvm/Support and make it cross-platform.
6711#ifdef __APPLE__
6712 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6713#endif
6714}
6715
6716void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6717 if (!Unit)
6718 return;
6719
6720 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6721 DEnd = Unit->stored_diag_end();
6722 D != DEnd; ++D) {
6723 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6724 CXString Msg = clang_formatDiagnostic(&Diag,
6725 clang_defaultDiagnosticDisplayOptions());
6726 fprintf(stderr, "%s\n", clang_getCString(Msg));
6727 clang_disposeString(Msg);
6728 }
6729#ifdef LLVM_ON_WIN32
6730 // On Windows, force a flush, since there may be multiple copies of
6731 // stderr and stdout in the file system, all with different buffers
6732 // but writing to the same device.
6733 fflush(stderr);
6734#endif
6735}
6736
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006737MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6738 SourceLocation MacroDefLoc,
6739 CXTranslationUnit TU){
6740 if (MacroDefLoc.isInvalid() || !TU)
6741 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006742 if (!II.hadMacroDefinition())
6743 return 0;
6744
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006745 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006746 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006747 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006748 if (MD) {
6749 for (MacroDirective::DefInfo
6750 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6751 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6752 return Def.getMacroInfo();
6753 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006754 }
6755
6756 return 0;
6757}
6758
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006759const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6760 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006761 if (!MacroDef || !TU)
6762 return 0;
6763 const IdentifierInfo *II = MacroDef->getName();
6764 if (!II)
6765 return 0;
6766
6767 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6768}
6769
6770MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6771 const Token &Tok,
6772 CXTranslationUnit TU) {
6773 if (!MI || !TU)
6774 return 0;
6775 if (Tok.isNot(tok::raw_identifier))
6776 return 0;
6777
6778 if (MI->getNumTokens() == 0)
6779 return 0;
6780 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6781 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006782 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006783
6784 // Check that the token is inside the definition and not its argument list.
6785 SourceManager &SM = Unit->getSourceManager();
6786 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6787 return 0;
6788 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6789 return 0;
6790
6791 Preprocessor &PP = Unit->getPreprocessor();
6792 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6793 if (!PPRec)
6794 return 0;
6795
6796 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6797 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6798 if (!II.hadMacroDefinition())
6799 return 0;
6800
6801 // Check that the identifier is not one of the macro arguments.
6802 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6803 return 0;
6804
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006805 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6806 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006807 return 0;
6808
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006809 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006810}
6811
6812MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6813 SourceLocation Loc,
6814 CXTranslationUnit TU) {
6815 if (Loc.isInvalid() || !MI || !TU)
6816 return 0;
6817
6818 if (MI->getNumTokens() == 0)
6819 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006820 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006821 Preprocessor &PP = Unit->getPreprocessor();
6822 if (!PP.getPreprocessingRecord())
6823 return 0;
6824 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6825 Token Tok;
6826 if (PP.getRawToken(Loc, Tok))
6827 return 0;
6828
6829 return checkForMacroInMacroDefinition(MI, Tok, TU);
6830}
6831
Guy Benyei11169dd2012-12-18 14:30:41 +00006832extern "C" {
6833
6834CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006835 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006836}
6837
6838} // end: extern "C"
6839
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006840Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6841 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006842 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006843 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006844 if (Unit->isMainFileAST())
6845 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006846 return *this;
6847 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006848 } else {
6849 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006850 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006851 return *this;
6852}
6853
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006854Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6855 *this << FE->getName();
6856 return *this;
6857}
6858
6859Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6860 CXString cursorName = clang_getCursorDisplayName(cursor);
6861 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6862 clang_disposeString(cursorName);
6863 return *this;
6864}
6865
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006866Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6867 CXFile File;
6868 unsigned Line, Column;
6869 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6870 CXString FileName = clang_getFileName(File);
6871 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6872 clang_disposeString(FileName);
6873 return *this;
6874}
6875
6876Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6877 CXSourceLocation BLoc = clang_getRangeStart(range);
6878 CXSourceLocation ELoc = clang_getRangeEnd(range);
6879
6880 CXFile BFile;
6881 unsigned BLine, BColumn;
6882 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6883
6884 CXFile EFile;
6885 unsigned ELine, EColumn;
6886 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6887
6888 CXString BFileName = clang_getFileName(BFile);
6889 if (BFile == EFile) {
6890 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6891 BLine, BColumn, ELine, EColumn);
6892 } else {
6893 CXString EFileName = clang_getFileName(EFile);
6894 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6895 BLine, BColumn)
6896 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6897 ELine, EColumn);
6898 clang_disposeString(EFileName);
6899 }
6900 clang_disposeString(BFileName);
6901 return *this;
6902}
6903
6904Logger &cxindex::Logger::operator<<(CXString Str) {
6905 *this << clang_getCString(Str);
6906 return *this;
6907}
6908
6909Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6910 LogOS << Fmt;
6911 return *this;
6912}
6913
6914cxindex::Logger::~Logger() {
6915 LogOS.flush();
6916
6917 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6918
6919 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6920
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006921 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006922 OS << "[libclang:" << Name << ':';
6923
6924 // FIXME: Portability.
6925#if HAVE_PTHREAD_H && __APPLE__
6926 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6927 OS << tid << ':';
6928#endif
6929
6930 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6931 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6932 OS << Msg.str() << '\n';
6933
6934 if (Trace) {
6935 llvm::sys::PrintStackTrace(stderr);
6936 OS << "--------------------------------------------------\n";
6937 }
6938}