blob: 626910b280697cf8d24ac4908735cf9f9c61ce5c [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
317 llvm::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
318 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)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003401 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003402 if (D)
3403 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003404 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003405 }
3406
3407 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003408 const Stmt *S = getCursorStmt(C);
3409 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003410 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003411
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003412 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003413 }
3414
3415 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003416 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003417 ->getNameStart());
3418
3419 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003420 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003421 ->getNameStart());
3422
3423 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003424 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003425
3426 if (clang_isDeclaration(C.kind))
3427 return getDeclSpelling(getCursorDecl(C));
3428
3429 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003430 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003431 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003432 }
3433
3434 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003435 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003436 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003437 }
3438
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003439 if (C.kind == CXCursor_PackedAttr) {
3440 return cxstring::createRef("packed");
3441 }
3442
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003443 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003444}
3445
3446CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3447 unsigned pieceIndex,
3448 unsigned options) {
3449 if (clang_Cursor_isNull(C))
3450 return clang_getNullRange();
3451
3452 ASTContext &Ctx = getCursorContext(C);
3453
3454 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003455 const Stmt *S = getCursorStmt(C);
3456 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003457 if (pieceIndex > 0)
3458 return clang_getNullRange();
3459 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3460 }
3461
3462 return clang_getNullRange();
3463 }
3464
3465 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003466 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003467 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3468 if (pieceIndex >= ME->getNumSelectorLocs())
3469 return clang_getNullRange();
3470 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3471 }
3472 }
3473
3474 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3475 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003476 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003477 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3478 if (pieceIndex >= MD->getNumSelectorLocs())
3479 return clang_getNullRange();
3480 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3481 }
3482 }
3483
3484 if (C.kind == CXCursor_ObjCCategoryDecl ||
3485 C.kind == CXCursor_ObjCCategoryImplDecl) {
3486 if (pieceIndex > 0)
3487 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003488 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003489 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3490 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003491 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003492 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3493 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3494 }
3495
3496 if (C.kind == CXCursor_ModuleImportDecl) {
3497 if (pieceIndex > 0)
3498 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003499 if (const ImportDecl *ImportD =
3500 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003501 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3502 if (!Locs.empty())
3503 return cxloc::translateSourceRange(Ctx,
3504 SourceRange(Locs.front(), Locs.back()));
3505 }
3506 return clang_getNullRange();
3507 }
3508
3509 // FIXME: A CXCursor_InclusionDirective should give the location of the
3510 // filename, but we don't keep track of this.
3511
3512 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3513 // but we don't keep track of this.
3514
3515 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3516 // but we don't keep track of this.
3517
3518 // Default handling, give the location of the cursor.
3519
3520 if (pieceIndex > 0)
3521 return clang_getNullRange();
3522
3523 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3524 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3525 return cxloc::translateSourceRange(Ctx, Loc);
3526}
3527
3528CXString clang_getCursorDisplayName(CXCursor C) {
3529 if (!clang_isDeclaration(C.kind))
3530 return clang_getCursorSpelling(C);
3531
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003532 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003534 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003535
3536 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003537 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003538 D = FunTmpl->getTemplatedDecl();
3539
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003540 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003541 SmallString<64> Str;
3542 llvm::raw_svector_ostream OS(Str);
3543 OS << *Function;
3544 if (Function->getPrimaryTemplate())
3545 OS << "<>";
3546 OS << "(";
3547 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3548 if (I)
3549 OS << ", ";
3550 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3551 }
3552
3553 if (Function->isVariadic()) {
3554 if (Function->getNumParams())
3555 OS << ", ";
3556 OS << "...";
3557 }
3558 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003559 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003560 }
3561
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003562 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003563 SmallString<64> Str;
3564 llvm::raw_svector_ostream OS(Str);
3565 OS << *ClassTemplate;
3566 OS << "<";
3567 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3568 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3569 if (I)
3570 OS << ", ";
3571
3572 NamedDecl *Param = Params->getParam(I);
3573 if (Param->getIdentifier()) {
3574 OS << Param->getIdentifier()->getName();
3575 continue;
3576 }
3577
3578 // There is no parameter name, which makes this tricky. Try to come up
3579 // with something useful that isn't too long.
3580 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3581 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3582 else if (NonTypeTemplateParmDecl *NTTP
3583 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3584 OS << NTTP->getType().getAsString(Policy);
3585 else
3586 OS << "template<...> class";
3587 }
3588
3589 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003590 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003591 }
3592
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003593 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3595 // If the type was explicitly written, use that.
3596 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003597 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003598
Benjamin Kramer9170e912013-02-22 15:46:01 +00003599 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003600 llvm::raw_svector_ostream OS(Str);
3601 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003602 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003603 ClassSpec->getTemplateArgs().data(),
3604 ClassSpec->getTemplateArgs().size(),
3605 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003606 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003607 }
3608
3609 return clang_getCursorSpelling(C);
3610}
3611
3612CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3613 switch (Kind) {
3614 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003615 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003616 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003617 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003618 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003619 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003620 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003621 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003622 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003623 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003624 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003625 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003626 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003627 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003628 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003629 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003630 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003631 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003632 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003633 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003635 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003637 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003641 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003643 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003645 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003647 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003651 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003653 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003655 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003659 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003663 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003665 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003673 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003742 case CXCursor_ObjCSelfExpr:
3743 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003860 case CXCursor_PackedAttr:
3861 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003910 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003911 return cxstring::createRef("OMPParallelDirective");
3912 case CXCursor_OMPSimdDirective:
3913 return cxstring::createRef("OMPSimdDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 }
3915
3916 llvm_unreachable("Unhandled CXCursorKind");
3917}
3918
3919struct GetCursorData {
3920 SourceLocation TokenBeginLoc;
3921 bool PointsAtMacroArgExpansion;
3922 bool VisitedObjCPropertyImplDecl;
3923 SourceLocation VisitedDeclaratorDeclStartLoc;
3924 CXCursor &BestCursor;
3925
3926 GetCursorData(SourceManager &SM,
3927 SourceLocation tokenBegin, CXCursor &outputCursor)
3928 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3929 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3930 VisitedObjCPropertyImplDecl = false;
3931 }
3932};
3933
3934static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3935 CXCursor parent,
3936 CXClientData client_data) {
3937 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3938 CXCursor *BestCursor = &Data->BestCursor;
3939
3940 // If we point inside a macro argument we should provide info of what the
3941 // token is so use the actual cursor, don't replace it with a macro expansion
3942 // cursor.
3943 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3944 return CXChildVisit_Recurse;
3945
3946 if (clang_isDeclaration(cursor.kind)) {
3947 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003948 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003949 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3950 if (MD->isImplicit())
3951 return CXChildVisit_Break;
3952
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003953 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3955 // Check that when we have multiple @class references in the same line,
3956 // that later ones do not override the previous ones.
3957 // If we have:
3958 // @class Foo, Bar;
3959 // source ranges for both start at '@', so 'Bar' will end up overriding
3960 // 'Foo' even though the cursor location was at 'Foo'.
3961 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3962 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003963 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3965 if (PrevID != ID &&
3966 !PrevID->isThisDeclarationADefinition() &&
3967 !ID->isThisDeclarationADefinition())
3968 return CXChildVisit_Break;
3969 }
3970
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003971 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3973 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3974 // Check that when we have multiple declarators in the same line,
3975 // that later ones do not override the previous ones.
3976 // If we have:
3977 // int Foo, Bar;
3978 // source ranges for both start at 'int', so 'Bar' will end up overriding
3979 // 'Foo' even though the cursor location was at 'Foo'.
3980 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3981 return CXChildVisit_Break;
3982 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3983
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003984 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003985 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3986 (void)PropImp;
3987 // Check that when we have multiple @synthesize in the same line,
3988 // that later ones do not override the previous ones.
3989 // If we have:
3990 // @synthesize Foo, Bar;
3991 // source ranges for both start at '@', so 'Bar' will end up overriding
3992 // 'Foo' even though the cursor location was at 'Foo'.
3993 if (Data->VisitedObjCPropertyImplDecl)
3994 return CXChildVisit_Break;
3995 Data->VisitedObjCPropertyImplDecl = true;
3996 }
3997 }
3998
3999 if (clang_isExpression(cursor.kind) &&
4000 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004001 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004002 // Avoid having the cursor of an expression replace the declaration cursor
4003 // when the expression source range overlaps the declaration range.
4004 // This can happen for C++ constructor expressions whose range generally
4005 // include the variable declaration, e.g.:
4006 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4007 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4008 D->getLocation() == Data->TokenBeginLoc)
4009 return CXChildVisit_Break;
4010 }
4011 }
4012
4013 // If our current best cursor is the construction of a temporary object,
4014 // don't replace that cursor with a type reference, because we want
4015 // clang_getCursor() to point at the constructor.
4016 if (clang_isExpression(BestCursor->kind) &&
4017 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4018 cursor.kind == CXCursor_TypeRef) {
4019 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4020 // as having the actual point on the type reference.
4021 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4022 return CXChildVisit_Recurse;
4023 }
4024
4025 *BestCursor = cursor;
4026 return CXChildVisit_Recurse;
4027}
4028
4029CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004030 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004031 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004032 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004033 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004034
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004035 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4037
4038 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4039 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4040
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004041 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 CXFile SearchFile;
4043 unsigned SearchLine, SearchColumn;
4044 CXFile ResultFile;
4045 unsigned ResultLine, ResultColumn;
4046 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4047 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4048 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4049
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004050 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4051 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 &ResultColumn, 0);
4053 SearchFileName = clang_getFileName(SearchFile);
4054 ResultFileName = clang_getFileName(ResultFile);
4055 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4056 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004057 *Log << llvm::format("(%s:%d:%d) = %s",
4058 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4059 clang_getCString(KindSpelling))
4060 << llvm::format("(%s:%d:%d):%s%s",
4061 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4062 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004063 clang_disposeString(SearchFileName);
4064 clang_disposeString(ResultFileName);
4065 clang_disposeString(KindSpelling);
4066 clang_disposeString(USR);
4067
4068 CXCursor Definition = clang_getCursorDefinition(Result);
4069 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4070 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4071 CXString DefinitionKindSpelling
4072 = clang_getCursorKindSpelling(Definition.kind);
4073 CXFile DefinitionFile;
4074 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004075 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004076 &DefinitionLine, &DefinitionColumn, 0);
4077 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004078 *Log << llvm::format(" -> %s(%s:%d:%d)",
4079 clang_getCString(DefinitionKindSpelling),
4080 clang_getCString(DefinitionFileName),
4081 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 clang_disposeString(DefinitionFileName);
4083 clang_disposeString(DefinitionKindSpelling);
4084 }
4085 }
4086
4087 return Result;
4088}
4089
4090CXCursor clang_getNullCursor(void) {
4091 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4092}
4093
4094unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004095 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4096 // can't set consistently. For example, when visiting a DeclStmt we will set
4097 // it but we don't set it on the result of clang_getCursorDefinition for
4098 // a reference of the same declaration.
4099 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4100 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4101 // to provide that kind of info.
4102 if (clang_isDeclaration(X.kind))
4103 X.data[1] = 0;
4104 if (clang_isDeclaration(Y.kind))
4105 Y.data[1] = 0;
4106
Guy Benyei11169dd2012-12-18 14:30:41 +00004107 return X == Y;
4108}
4109
4110unsigned clang_hashCursor(CXCursor C) {
4111 unsigned Index = 0;
4112 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4113 Index = 1;
4114
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004115 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 std::make_pair(C.kind, C.data[Index]));
4117}
4118
4119unsigned clang_isInvalid(enum CXCursorKind K) {
4120 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4121}
4122
4123unsigned clang_isDeclaration(enum CXCursorKind K) {
4124 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4125 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4126}
4127
4128unsigned clang_isReference(enum CXCursorKind K) {
4129 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4130}
4131
4132unsigned clang_isExpression(enum CXCursorKind K) {
4133 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4134}
4135
4136unsigned clang_isStatement(enum CXCursorKind K) {
4137 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4138}
4139
4140unsigned clang_isAttribute(enum CXCursorKind K) {
4141 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4142}
4143
4144unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4145 return K == CXCursor_TranslationUnit;
4146}
4147
4148unsigned clang_isPreprocessing(enum CXCursorKind K) {
4149 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4150}
4151
4152unsigned clang_isUnexposed(enum CXCursorKind K) {
4153 switch (K) {
4154 case CXCursor_UnexposedDecl:
4155 case CXCursor_UnexposedExpr:
4156 case CXCursor_UnexposedStmt:
4157 case CXCursor_UnexposedAttr:
4158 return true;
4159 default:
4160 return false;
4161 }
4162}
4163
4164CXCursorKind clang_getCursorKind(CXCursor C) {
4165 return C.kind;
4166}
4167
4168CXSourceLocation clang_getCursorLocation(CXCursor C) {
4169 if (clang_isReference(C.kind)) {
4170 switch (C.kind) {
4171 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004172 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004173 = getCursorObjCSuperClassRef(C);
4174 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4175 }
4176
4177 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004178 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004179 = getCursorObjCProtocolRef(C);
4180 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4181 }
4182
4183 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004184 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004185 = getCursorObjCClassRef(C);
4186 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4187 }
4188
4189 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004190 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4192 }
4193
4194 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004195 std::pair<const TemplateDecl *, SourceLocation> P =
4196 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4198 }
4199
4200 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004201 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004202 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4203 }
4204
4205 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004206 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4208 }
4209
4210 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004211 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004212 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4213 }
4214
4215 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004216 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004217 if (!BaseSpec)
4218 return clang_getNullLocation();
4219
4220 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4221 return cxloc::translateSourceLocation(getCursorContext(C),
4222 TSInfo->getTypeLoc().getBeginLoc());
4223
4224 return cxloc::translateSourceLocation(getCursorContext(C),
4225 BaseSpec->getLocStart());
4226 }
4227
4228 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004229 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004230 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4231 }
4232
4233 case CXCursor_OverloadedDeclRef:
4234 return cxloc::translateSourceLocation(getCursorContext(C),
4235 getCursorOverloadedDeclRef(C).second);
4236
4237 default:
4238 // FIXME: Need a way to enumerate all non-reference cases.
4239 llvm_unreachable("Missed a reference kind");
4240 }
4241 }
4242
4243 if (clang_isExpression(C.kind))
4244 return cxloc::translateSourceLocation(getCursorContext(C),
4245 getLocationFromExpr(getCursorExpr(C)));
4246
4247 if (clang_isStatement(C.kind))
4248 return cxloc::translateSourceLocation(getCursorContext(C),
4249 getCursorStmt(C)->getLocStart());
4250
4251 if (C.kind == CXCursor_PreprocessingDirective) {
4252 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4253 return cxloc::translateSourceLocation(getCursorContext(C), L);
4254 }
4255
4256 if (C.kind == CXCursor_MacroExpansion) {
4257 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004258 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004259 return cxloc::translateSourceLocation(getCursorContext(C), L);
4260 }
4261
4262 if (C.kind == CXCursor_MacroDefinition) {
4263 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4264 return cxloc::translateSourceLocation(getCursorContext(C), L);
4265 }
4266
4267 if (C.kind == CXCursor_InclusionDirective) {
4268 SourceLocation L
4269 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4270 return cxloc::translateSourceLocation(getCursorContext(C), L);
4271 }
4272
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004273 if (clang_isAttribute(C.kind)) {
4274 SourceLocation L
4275 = cxcursor::getCursorAttr(C)->getLocation();
4276 return cxloc::translateSourceLocation(getCursorContext(C), L);
4277 }
4278
Guy Benyei11169dd2012-12-18 14:30:41 +00004279 if (!clang_isDeclaration(C.kind))
4280 return clang_getNullLocation();
4281
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004282 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004283 if (!D)
4284 return clang_getNullLocation();
4285
4286 SourceLocation Loc = D->getLocation();
4287 // FIXME: Multiple variables declared in a single declaration
4288 // currently lack the information needed to correctly determine their
4289 // ranges when accounting for the type-specifier. We use context
4290 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4291 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004292 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004293 if (!cxcursor::isFirstInDeclGroup(C))
4294 Loc = VD->getLocation();
4295 }
4296
4297 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004298 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004299 Loc = MD->getSelectorStartLoc();
4300
4301 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4302}
4303
4304} // end extern "C"
4305
4306CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4307 assert(TU);
4308
4309 // Guard against an invalid SourceLocation, or we may assert in one
4310 // of the following calls.
4311 if (SLoc.isInvalid())
4312 return clang_getNullCursor();
4313
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004314 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004315
4316 // Translate the given source location to make it point at the beginning of
4317 // the token under the cursor.
4318 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4319 CXXUnit->getASTContext().getLangOpts());
4320
4321 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4322 if (SLoc.isValid()) {
4323 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4324 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4325 /*VisitPreprocessorLast=*/true,
4326 /*VisitIncludedEntities=*/false,
4327 SourceLocation(SLoc));
4328 CursorVis.visitFileRegion();
4329 }
4330
4331 return Result;
4332}
4333
4334static SourceRange getRawCursorExtent(CXCursor C) {
4335 if (clang_isReference(C.kind)) {
4336 switch (C.kind) {
4337 case CXCursor_ObjCSuperClassRef:
4338 return getCursorObjCSuperClassRef(C).second;
4339
4340 case CXCursor_ObjCProtocolRef:
4341 return getCursorObjCProtocolRef(C).second;
4342
4343 case CXCursor_ObjCClassRef:
4344 return getCursorObjCClassRef(C).second;
4345
4346 case CXCursor_TypeRef:
4347 return getCursorTypeRef(C).second;
4348
4349 case CXCursor_TemplateRef:
4350 return getCursorTemplateRef(C).second;
4351
4352 case CXCursor_NamespaceRef:
4353 return getCursorNamespaceRef(C).second;
4354
4355 case CXCursor_MemberRef:
4356 return getCursorMemberRef(C).second;
4357
4358 case CXCursor_CXXBaseSpecifier:
4359 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4360
4361 case CXCursor_LabelRef:
4362 return getCursorLabelRef(C).second;
4363
4364 case CXCursor_OverloadedDeclRef:
4365 return getCursorOverloadedDeclRef(C).second;
4366
4367 case CXCursor_VariableRef:
4368 return getCursorVariableRef(C).second;
4369
4370 default:
4371 // FIXME: Need a way to enumerate all non-reference cases.
4372 llvm_unreachable("Missed a reference kind");
4373 }
4374 }
4375
4376 if (clang_isExpression(C.kind))
4377 return getCursorExpr(C)->getSourceRange();
4378
4379 if (clang_isStatement(C.kind))
4380 return getCursorStmt(C)->getSourceRange();
4381
4382 if (clang_isAttribute(C.kind))
4383 return getCursorAttr(C)->getRange();
4384
4385 if (C.kind == CXCursor_PreprocessingDirective)
4386 return cxcursor::getCursorPreprocessingDirective(C);
4387
4388 if (C.kind == CXCursor_MacroExpansion) {
4389 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004390 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004391 return TU->mapRangeFromPreamble(Range);
4392 }
4393
4394 if (C.kind == CXCursor_MacroDefinition) {
4395 ASTUnit *TU = getCursorASTUnit(C);
4396 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4397 return TU->mapRangeFromPreamble(Range);
4398 }
4399
4400 if (C.kind == CXCursor_InclusionDirective) {
4401 ASTUnit *TU = getCursorASTUnit(C);
4402 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4403 return TU->mapRangeFromPreamble(Range);
4404 }
4405
4406 if (C.kind == CXCursor_TranslationUnit) {
4407 ASTUnit *TU = getCursorASTUnit(C);
4408 FileID MainID = TU->getSourceManager().getMainFileID();
4409 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4410 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4411 return SourceRange(Start, End);
4412 }
4413
4414 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004415 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004416 if (!D)
4417 return SourceRange();
4418
4419 SourceRange R = D->getSourceRange();
4420 // FIXME: Multiple variables declared in a single declaration
4421 // currently lack the information needed to correctly determine their
4422 // ranges when accounting for the type-specifier. We use context
4423 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4424 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004425 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004426 if (!cxcursor::isFirstInDeclGroup(C))
4427 R.setBegin(VD->getLocation());
4428 }
4429 return R;
4430 }
4431 return SourceRange();
4432}
4433
4434/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4435/// the decl-specifier-seq for declarations.
4436static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4437 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004438 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004439 if (!D)
4440 return SourceRange();
4441
4442 SourceRange R = D->getSourceRange();
4443
4444 // Adjust the start of the location for declarations preceded by
4445 // declaration specifiers.
4446 SourceLocation StartLoc;
4447 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4448 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4449 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004450 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004451 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4452 StartLoc = TI->getTypeLoc().getLocStart();
4453 }
4454
4455 if (StartLoc.isValid() && R.getBegin().isValid() &&
4456 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4457 R.setBegin(StartLoc);
4458
4459 // FIXME: Multiple variables declared in a single declaration
4460 // currently lack the information needed to correctly determine their
4461 // ranges when accounting for the type-specifier. We use context
4462 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4463 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004464 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004465 if (!cxcursor::isFirstInDeclGroup(C))
4466 R.setBegin(VD->getLocation());
4467 }
4468
4469 return R;
4470 }
4471
4472 return getRawCursorExtent(C);
4473}
4474
4475extern "C" {
4476
4477CXSourceRange clang_getCursorExtent(CXCursor C) {
4478 SourceRange R = getRawCursorExtent(C);
4479 if (R.isInvalid())
4480 return clang_getNullRange();
4481
4482 return cxloc::translateSourceRange(getCursorContext(C), R);
4483}
4484
4485CXCursor clang_getCursorReferenced(CXCursor C) {
4486 if (clang_isInvalid(C.kind))
4487 return clang_getNullCursor();
4488
4489 CXTranslationUnit tu = getCursorTU(C);
4490 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004491 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004492 if (!D)
4493 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004494 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004495 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004496 if (const ObjCPropertyImplDecl *PropImpl =
4497 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004498 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4499 return MakeCXCursor(Property, tu);
4500
4501 return C;
4502 }
4503
4504 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004505 const Expr *E = getCursorExpr(C);
4506 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004507 if (D) {
4508 CXCursor declCursor = MakeCXCursor(D, tu);
4509 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4510 declCursor);
4511 return declCursor;
4512 }
4513
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004514 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004515 return MakeCursorOverloadedDeclRef(Ovl, tu);
4516
4517 return clang_getNullCursor();
4518 }
4519
4520 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004521 const Stmt *S = getCursorStmt(C);
4522 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004523 if (LabelDecl *label = Goto->getLabel())
4524 if (LabelStmt *labelS = label->getStmt())
4525 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4526
4527 return clang_getNullCursor();
4528 }
4529
4530 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004531 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004532 return MakeMacroDefinitionCursor(Def, tu);
4533 }
4534
4535 if (!clang_isReference(C.kind))
4536 return clang_getNullCursor();
4537
4538 switch (C.kind) {
4539 case CXCursor_ObjCSuperClassRef:
4540 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4541
4542 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004543 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4544 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 return MakeCXCursor(Def, tu);
4546
4547 return MakeCXCursor(Prot, tu);
4548 }
4549
4550 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004551 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4552 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004553 return MakeCXCursor(Def, tu);
4554
4555 return MakeCXCursor(Class, tu);
4556 }
4557
4558 case CXCursor_TypeRef:
4559 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4560
4561 case CXCursor_TemplateRef:
4562 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4563
4564 case CXCursor_NamespaceRef:
4565 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4566
4567 case CXCursor_MemberRef:
4568 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4569
4570 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004571 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004572 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4573 tu ));
4574 }
4575
4576 case CXCursor_LabelRef:
4577 // FIXME: We end up faking the "parent" declaration here because we
4578 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004579 return MakeCXCursor(getCursorLabelRef(C).first,
4580 cxtu::getASTUnit(tu)->getASTContext()
4581 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004582 tu);
4583
4584 case CXCursor_OverloadedDeclRef:
4585 return C;
4586
4587 case CXCursor_VariableRef:
4588 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4589
4590 default:
4591 // We would prefer to enumerate all non-reference cursor kinds here.
4592 llvm_unreachable("Unhandled reference cursor kind");
4593 }
4594}
4595
4596CXCursor clang_getCursorDefinition(CXCursor C) {
4597 if (clang_isInvalid(C.kind))
4598 return clang_getNullCursor();
4599
4600 CXTranslationUnit TU = getCursorTU(C);
4601
4602 bool WasReference = false;
4603 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4604 C = clang_getCursorReferenced(C);
4605 WasReference = true;
4606 }
4607
4608 if (C.kind == CXCursor_MacroExpansion)
4609 return clang_getCursorReferenced(C);
4610
4611 if (!clang_isDeclaration(C.kind))
4612 return clang_getNullCursor();
4613
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004614 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004615 if (!D)
4616 return clang_getNullCursor();
4617
4618 switch (D->getKind()) {
4619 // Declaration kinds that don't really separate the notions of
4620 // declaration and definition.
4621 case Decl::Namespace:
4622 case Decl::Typedef:
4623 case Decl::TypeAlias:
4624 case Decl::TypeAliasTemplate:
4625 case Decl::TemplateTypeParm:
4626 case Decl::EnumConstant:
4627 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004628 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004629 case Decl::IndirectField:
4630 case Decl::ObjCIvar:
4631 case Decl::ObjCAtDefsField:
4632 case Decl::ImplicitParam:
4633 case Decl::ParmVar:
4634 case Decl::NonTypeTemplateParm:
4635 case Decl::TemplateTemplateParm:
4636 case Decl::ObjCCategoryImpl:
4637 case Decl::ObjCImplementation:
4638 case Decl::AccessSpec:
4639 case Decl::LinkageSpec:
4640 case Decl::ObjCPropertyImpl:
4641 case Decl::FileScopeAsm:
4642 case Decl::StaticAssert:
4643 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004644 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 case Decl::Label: // FIXME: Is this right??
4646 case Decl::ClassScopeFunctionSpecialization:
4647 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004648 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004649 return C;
4650
4651 // Declaration kinds that don't make any sense here, but are
4652 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004653 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004654 case Decl::TranslationUnit:
4655 break;
4656
4657 // Declaration kinds for which the definition is not resolvable.
4658 case Decl::UnresolvedUsingTypename:
4659 case Decl::UnresolvedUsingValue:
4660 break;
4661
4662 case Decl::UsingDirective:
4663 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4664 TU);
4665
4666 case Decl::NamespaceAlias:
4667 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4668
4669 case Decl::Enum:
4670 case Decl::Record:
4671 case Decl::CXXRecord:
4672 case Decl::ClassTemplateSpecialization:
4673 case Decl::ClassTemplatePartialSpecialization:
4674 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4675 return MakeCXCursor(Def, TU);
4676 return clang_getNullCursor();
4677
4678 case Decl::Function:
4679 case Decl::CXXMethod:
4680 case Decl::CXXConstructor:
4681 case Decl::CXXDestructor:
4682 case Decl::CXXConversion: {
4683 const FunctionDecl *Def = 0;
4684 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004685 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004686 return clang_getNullCursor();
4687 }
4688
Larisse Voufo39a1e502013-08-06 01:03:05 +00004689 case Decl::Var:
4690 case Decl::VarTemplateSpecialization:
4691 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004692 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004693 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004694 return MakeCXCursor(Def, TU);
4695 return clang_getNullCursor();
4696 }
4697
4698 case Decl::FunctionTemplate: {
4699 const FunctionDecl *Def = 0;
4700 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4701 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4702 return clang_getNullCursor();
4703 }
4704
4705 case Decl::ClassTemplate: {
4706 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4707 ->getDefinition())
4708 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4709 TU);
4710 return clang_getNullCursor();
4711 }
4712
Larisse Voufo39a1e502013-08-06 01:03:05 +00004713 case Decl::VarTemplate: {
4714 if (VarDecl *Def =
4715 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4716 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4717 return clang_getNullCursor();
4718 }
4719
Guy Benyei11169dd2012-12-18 14:30:41 +00004720 case Decl::Using:
4721 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4722 D->getLocation(), TU);
4723
4724 case Decl::UsingShadow:
4725 return clang_getCursorDefinition(
4726 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4727 TU));
4728
4729 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004730 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004731 if (Method->isThisDeclarationADefinition())
4732 return C;
4733
4734 // Dig out the method definition in the associated
4735 // @implementation, if we have it.
4736 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004737 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004738 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4739 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4740 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4741 Method->isInstanceMethod()))
4742 if (Def->isThisDeclarationADefinition())
4743 return MakeCXCursor(Def, TU);
4744
4745 return clang_getNullCursor();
4746 }
4747
4748 case Decl::ObjCCategory:
4749 if (ObjCCategoryImplDecl *Impl
4750 = cast<ObjCCategoryDecl>(D)->getImplementation())
4751 return MakeCXCursor(Impl, TU);
4752 return clang_getNullCursor();
4753
4754 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004755 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004756 return MakeCXCursor(Def, TU);
4757 return clang_getNullCursor();
4758
4759 case Decl::ObjCInterface: {
4760 // There are two notions of a "definition" for an Objective-C
4761 // class: the interface and its implementation. When we resolved a
4762 // reference to an Objective-C class, produce the @interface as
4763 // the definition; when we were provided with the interface,
4764 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004765 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004766 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004767 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004768 return MakeCXCursor(Def, TU);
4769 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4770 return MakeCXCursor(Impl, TU);
4771 return clang_getNullCursor();
4772 }
4773
4774 case Decl::ObjCProperty:
4775 // FIXME: We don't really know where to find the
4776 // ObjCPropertyImplDecls that implement this property.
4777 return clang_getNullCursor();
4778
4779 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004780 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004781 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004782 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004783 return MakeCXCursor(Def, TU);
4784
4785 return clang_getNullCursor();
4786
4787 case Decl::Friend:
4788 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4789 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4790 return clang_getNullCursor();
4791
4792 case Decl::FriendTemplate:
4793 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4794 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4795 return clang_getNullCursor();
4796 }
4797
4798 return clang_getNullCursor();
4799}
4800
4801unsigned clang_isCursorDefinition(CXCursor C) {
4802 if (!clang_isDeclaration(C.kind))
4803 return 0;
4804
4805 return clang_getCursorDefinition(C) == C;
4806}
4807
4808CXCursor clang_getCanonicalCursor(CXCursor C) {
4809 if (!clang_isDeclaration(C.kind))
4810 return C;
4811
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004812 if (const Decl *D = getCursorDecl(C)) {
4813 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004814 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4815 return MakeCXCursor(CatD, getCursorTU(C));
4816
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004817 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4818 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004819 return MakeCXCursor(IFD, getCursorTU(C));
4820
4821 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4822 }
4823
4824 return C;
4825}
4826
4827int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4828 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4829}
4830
4831unsigned clang_getNumOverloadedDecls(CXCursor C) {
4832 if (C.kind != CXCursor_OverloadedDeclRef)
4833 return 0;
4834
4835 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004836 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004837 return E->getNumDecls();
4838
4839 if (OverloadedTemplateStorage *S
4840 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4841 return S->size();
4842
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004843 const Decl *D = Storage.get<const Decl *>();
4844 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004845 return Using->shadow_size();
4846
4847 return 0;
4848}
4849
4850CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4851 if (cursor.kind != CXCursor_OverloadedDeclRef)
4852 return clang_getNullCursor();
4853
4854 if (index >= clang_getNumOverloadedDecls(cursor))
4855 return clang_getNullCursor();
4856
4857 CXTranslationUnit TU = getCursorTU(cursor);
4858 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004859 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004860 return MakeCXCursor(E->decls_begin()[index], TU);
4861
4862 if (OverloadedTemplateStorage *S
4863 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4864 return MakeCXCursor(S->begin()[index], TU);
4865
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004866 const Decl *D = Storage.get<const Decl *>();
4867 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004868 // FIXME: This is, unfortunately, linear time.
4869 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4870 std::advance(Pos, index);
4871 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4872 }
4873
4874 return clang_getNullCursor();
4875}
4876
4877void clang_getDefinitionSpellingAndExtent(CXCursor C,
4878 const char **startBuf,
4879 const char **endBuf,
4880 unsigned *startLine,
4881 unsigned *startColumn,
4882 unsigned *endLine,
4883 unsigned *endColumn) {
4884 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004885 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004886 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4887
4888 SourceManager &SM = FD->getASTContext().getSourceManager();
4889 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4890 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4891 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4892 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4893 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4894 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4895}
4896
4897
4898CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4899 unsigned PieceIndex) {
4900 RefNamePieces Pieces;
4901
4902 switch (C.kind) {
4903 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004904 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004905 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4906 E->getQualifierLoc().getSourceRange());
4907 break;
4908
4909 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004910 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004911 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4912 E->getQualifierLoc().getSourceRange(),
4913 E->getOptionalExplicitTemplateArgs());
4914 break;
4915
4916 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004917 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004918 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004919 const Expr *Callee = OCE->getCallee();
4920 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004921 Callee = ICE->getSubExpr();
4922
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004923 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004924 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4925 DRE->getQualifierLoc().getSourceRange());
4926 }
4927 break;
4928
4929 default:
4930 break;
4931 }
4932
4933 if (Pieces.empty()) {
4934 if (PieceIndex == 0)
4935 return clang_getCursorExtent(C);
4936 } else if (PieceIndex < Pieces.size()) {
4937 SourceRange R = Pieces[PieceIndex];
4938 if (R.isValid())
4939 return cxloc::translateSourceRange(getCursorContext(C), R);
4940 }
4941
4942 return clang_getNullRange();
4943}
4944
4945void clang_enableStackTraces(void) {
4946 llvm::sys::PrintStackTraceOnErrorSignal();
4947}
4948
4949void clang_executeOnThread(void (*fn)(void*), void *user_data,
4950 unsigned stack_size) {
4951 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4952}
4953
4954} // end: extern "C"
4955
4956//===----------------------------------------------------------------------===//
4957// Token-based Operations.
4958//===----------------------------------------------------------------------===//
4959
4960/* CXToken layout:
4961 * int_data[0]: a CXTokenKind
4962 * int_data[1]: starting token location
4963 * int_data[2]: token length
4964 * int_data[3]: reserved
4965 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4966 * otherwise unused.
4967 */
4968extern "C" {
4969
4970CXTokenKind clang_getTokenKind(CXToken CXTok) {
4971 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4972}
4973
4974CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4975 switch (clang_getTokenKind(CXTok)) {
4976 case CXToken_Identifier:
4977 case CXToken_Keyword:
4978 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004979 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004980 ->getNameStart());
4981
4982 case CXToken_Literal: {
4983 // We have stashed the starting pointer in the ptr_data field. Use it.
4984 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004985 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004986 }
4987
4988 case CXToken_Punctuation:
4989 case CXToken_Comment:
4990 break;
4991 }
4992
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004993 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004994 LOG_BAD_TU(TU);
4995 return cxstring::createEmpty();
4996 }
4997
Guy Benyei11169dd2012-12-18 14:30:41 +00004998 // We have to find the starting buffer pointer the hard way, by
4999 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005000 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005001 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005002 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005003
5004 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5005 std::pair<FileID, unsigned> LocInfo
5006 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5007 bool Invalid = false;
5008 StringRef Buffer
5009 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5010 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005011 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005012
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005013 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005014}
5015
5016CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005017 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005018 LOG_BAD_TU(TU);
5019 return clang_getNullLocation();
5020 }
5021
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005022 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005023 if (!CXXUnit)
5024 return clang_getNullLocation();
5025
5026 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5027 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5028}
5029
5030CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005031 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005032 LOG_BAD_TU(TU);
5033 return clang_getNullRange();
5034 }
5035
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005036 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005037 if (!CXXUnit)
5038 return clang_getNullRange();
5039
5040 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5041 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5042}
5043
5044static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5045 SmallVectorImpl<CXToken> &CXTokens) {
5046 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5047 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005048 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005049 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005050 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005051
5052 // Cannot tokenize across files.
5053 if (BeginLocInfo.first != EndLocInfo.first)
5054 return;
5055
5056 // Create a lexer
5057 bool Invalid = false;
5058 StringRef Buffer
5059 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5060 if (Invalid)
5061 return;
5062
5063 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5064 CXXUnit->getASTContext().getLangOpts(),
5065 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5066 Lex.SetCommentRetentionState(true);
5067
5068 // Lex tokens until we hit the end of the range.
5069 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5070 Token Tok;
5071 bool previousWasAt = false;
5072 do {
5073 // Lex the next token
5074 Lex.LexFromRawLexer(Tok);
5075 if (Tok.is(tok::eof))
5076 break;
5077
5078 // Initialize the CXToken.
5079 CXToken CXTok;
5080
5081 // - Common fields
5082 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5083 CXTok.int_data[2] = Tok.getLength();
5084 CXTok.int_data[3] = 0;
5085
5086 // - Kind-specific fields
5087 if (Tok.isLiteral()) {
5088 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005089 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005090 } else if (Tok.is(tok::raw_identifier)) {
5091 // Lookup the identifier to determine whether we have a keyword.
5092 IdentifierInfo *II
5093 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5094
5095 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5096 CXTok.int_data[0] = CXToken_Keyword;
5097 }
5098 else {
5099 CXTok.int_data[0] = Tok.is(tok::identifier)
5100 ? CXToken_Identifier
5101 : CXToken_Keyword;
5102 }
5103 CXTok.ptr_data = II;
5104 } else if (Tok.is(tok::comment)) {
5105 CXTok.int_data[0] = CXToken_Comment;
5106 CXTok.ptr_data = 0;
5107 } else {
5108 CXTok.int_data[0] = CXToken_Punctuation;
5109 CXTok.ptr_data = 0;
5110 }
5111 CXTokens.push_back(CXTok);
5112 previousWasAt = Tok.is(tok::at);
5113 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5114}
5115
5116void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5117 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005118 LOG_FUNC_SECTION {
5119 *Log << TU << ' ' << Range;
5120 }
5121
Guy Benyei11169dd2012-12-18 14:30:41 +00005122 if (Tokens)
5123 *Tokens = 0;
5124 if (NumTokens)
5125 *NumTokens = 0;
5126
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005127 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005128 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005129 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005130 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005131
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005132 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005133 if (!CXXUnit || !Tokens || !NumTokens)
5134 return;
5135
5136 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5137
5138 SourceRange R = cxloc::translateCXSourceRange(Range);
5139 if (R.isInvalid())
5140 return;
5141
5142 SmallVector<CXToken, 32> CXTokens;
5143 getTokens(CXXUnit, R, CXTokens);
5144
5145 if (CXTokens.empty())
5146 return;
5147
5148 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5149 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5150 *NumTokens = CXTokens.size();
5151}
5152
5153void clang_disposeTokens(CXTranslationUnit TU,
5154 CXToken *Tokens, unsigned NumTokens) {
5155 free(Tokens);
5156}
5157
5158} // end: extern "C"
5159
5160//===----------------------------------------------------------------------===//
5161// Token annotation APIs.
5162//===----------------------------------------------------------------------===//
5163
Guy Benyei11169dd2012-12-18 14:30:41 +00005164static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5165 CXCursor parent,
5166 CXClientData client_data);
5167static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5168 CXClientData client_data);
5169
5170namespace {
5171class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005172 CXToken *Tokens;
5173 CXCursor *Cursors;
5174 unsigned NumTokens;
5175 unsigned TokIdx;
5176 unsigned PreprocessingTokIdx;
5177 CursorVisitor AnnotateVis;
5178 SourceManager &SrcMgr;
5179 bool HasContextSensitiveKeywords;
5180
5181 struct PostChildrenInfo {
5182 CXCursor Cursor;
5183 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005184 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005185 unsigned BeforeChildrenTokenIdx;
5186 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005187 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005188
5189 CXToken &getTok(unsigned Idx) {
5190 assert(Idx < NumTokens);
5191 return Tokens[Idx];
5192 }
5193 const CXToken &getTok(unsigned Idx) const {
5194 assert(Idx < NumTokens);
5195 return Tokens[Idx];
5196 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005197 bool MoreTokens() const { return TokIdx < NumTokens; }
5198 unsigned NextToken() const { return TokIdx; }
5199 void AdvanceToken() { ++TokIdx; }
5200 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005201 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005202 }
5203 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005204 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005205 }
5206 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005207 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005208 }
5209
5210 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005211 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005212 SourceRange);
5213
5214public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005215 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005216 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005217 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005219 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005220 AnnotateTokensVisitor, this,
5221 /*VisitPreprocessorLast=*/true,
5222 /*VisitIncludedEntities=*/false,
5223 RegionOfInterest,
5224 /*VisitDeclsOnly=*/false,
5225 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005226 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005227 HasContextSensitiveKeywords(false) { }
5228
5229 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5230 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5231 bool postVisitChildren(CXCursor cursor);
5232 void AnnotateTokens();
5233
5234 /// \brief Determine whether the annotator saw any cursors that have
5235 /// context-sensitive keywords.
5236 bool hasContextSensitiveKeywords() const {
5237 return HasContextSensitiveKeywords;
5238 }
5239
5240 ~AnnotateTokensWorker() {
5241 assert(PostChildrenInfos.empty());
5242 }
5243};
5244}
5245
5246void AnnotateTokensWorker::AnnotateTokens() {
5247 // Walk the AST within the region of interest, annotating tokens
5248 // along the way.
5249 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005250}
Guy Benyei11169dd2012-12-18 14:30:41 +00005251
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005252static inline void updateCursorAnnotation(CXCursor &Cursor,
5253 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005254 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005255 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005256 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005257}
5258
5259/// \brief It annotates and advances tokens with a cursor until the comparison
5260//// between the cursor location and the source range is the same as
5261/// \arg compResult.
5262///
5263/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5264/// Pass RangeOverlap to annotate tokens inside a range.
5265void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5266 RangeComparisonResult compResult,
5267 SourceRange range) {
5268 while (MoreTokens()) {
5269 const unsigned I = NextToken();
5270 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005271 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5272 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005273
5274 SourceLocation TokLoc = GetTokenLoc(I);
5275 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005276 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005277 AdvanceToken();
5278 continue;
5279 }
5280 break;
5281 }
5282}
5283
5284/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005285/// \returns true if it advanced beyond all macro tokens, false otherwise.
5286bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005287 CXCursor updateC,
5288 RangeComparisonResult compResult,
5289 SourceRange range) {
5290 assert(MoreTokens());
5291 assert(isFunctionMacroToken(NextToken()) &&
5292 "Should be called only for macro arg tokens");
5293
5294 // This works differently than annotateAndAdvanceTokens; because expanded
5295 // macro arguments can have arbitrary translation-unit source order, we do not
5296 // advance the token index one by one until a token fails the range test.
5297 // We only advance once past all of the macro arg tokens if all of them
5298 // pass the range test. If one of them fails we keep the token index pointing
5299 // at the start of the macro arg tokens so that the failing token will be
5300 // annotated by a subsequent annotation try.
5301
5302 bool atLeastOneCompFail = false;
5303
5304 unsigned I = NextToken();
5305 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5306 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5307 if (TokLoc.isFileID())
5308 continue; // not macro arg token, it's parens or comma.
5309 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5310 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5311 Cursors[I] = updateC;
5312 } else
5313 atLeastOneCompFail = true;
5314 }
5315
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005316 if (atLeastOneCompFail)
5317 return false;
5318
5319 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5320 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005321}
5322
5323enum CXChildVisitResult
5324AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005325 SourceRange cursorRange = getRawCursorExtent(cursor);
5326 if (cursorRange.isInvalid())
5327 return CXChildVisit_Recurse;
5328
5329 if (!HasContextSensitiveKeywords) {
5330 // Objective-C properties can have context-sensitive keywords.
5331 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005332 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005333 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5334 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5335 }
5336 // Objective-C methods can have context-sensitive keywords.
5337 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5338 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005339 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005340 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5341 if (Method->getObjCDeclQualifier())
5342 HasContextSensitiveKeywords = true;
5343 else {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005344 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5345 PEnd = Method->param_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00005346 P != PEnd; ++P) {
5347 if ((*P)->getObjCDeclQualifier()) {
5348 HasContextSensitiveKeywords = true;
5349 break;
5350 }
5351 }
5352 }
5353 }
5354 }
5355 // C++ methods can have context-sensitive keywords.
5356 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005357 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005358 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5359 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5360 HasContextSensitiveKeywords = true;
5361 }
5362 }
5363 // C++ classes can have context-sensitive keywords.
5364 else if (cursor.kind == CXCursor_StructDecl ||
5365 cursor.kind == CXCursor_ClassDecl ||
5366 cursor.kind == CXCursor_ClassTemplate ||
5367 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005368 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005369 if (D->hasAttr<FinalAttr>())
5370 HasContextSensitiveKeywords = true;
5371 }
5372 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005373
5374 // Don't override a property annotation with its getter/setter method.
5375 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5376 parent.kind == CXCursor_ObjCPropertyDecl)
5377 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005378
5379 if (clang_isPreprocessing(cursor.kind)) {
5380 // Items in the preprocessing record are kept separate from items in
5381 // declarations, so we keep a separate token index.
5382 unsigned SavedTokIdx = TokIdx;
5383 TokIdx = PreprocessingTokIdx;
5384
5385 // Skip tokens up until we catch up to the beginning of the preprocessing
5386 // entry.
5387 while (MoreTokens()) {
5388 const unsigned I = NextToken();
5389 SourceLocation TokLoc = GetTokenLoc(I);
5390 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5391 case RangeBefore:
5392 AdvanceToken();
5393 continue;
5394 case RangeAfter:
5395 case RangeOverlap:
5396 break;
5397 }
5398 break;
5399 }
5400
5401 // Look at all of the tokens within this range.
5402 while (MoreTokens()) {
5403 const unsigned I = NextToken();
5404 SourceLocation TokLoc = GetTokenLoc(I);
5405 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5406 case RangeBefore:
5407 llvm_unreachable("Infeasible");
5408 case RangeAfter:
5409 break;
5410 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005411 // For macro expansions, just note where the beginning of the macro
5412 // expansion occurs.
5413 if (cursor.kind == CXCursor_MacroExpansion) {
5414 if (TokLoc == cursorRange.getBegin())
5415 Cursors[I] = cursor;
5416 AdvanceToken();
5417 break;
5418 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005419 // We may have already annotated macro names inside macro definitions.
5420 if (Cursors[I].kind != CXCursor_MacroExpansion)
5421 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005422 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005423 continue;
5424 }
5425 break;
5426 }
5427
5428 // Save the preprocessing token index; restore the non-preprocessing
5429 // token index.
5430 PreprocessingTokIdx = TokIdx;
5431 TokIdx = SavedTokIdx;
5432 return CXChildVisit_Recurse;
5433 }
5434
5435 if (cursorRange.isInvalid())
5436 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005437
5438 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005439 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005440 const enum CXCursorKind K = clang_getCursorKind(parent);
5441 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005442 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5443 // Attributes are annotated out-of-order, skip tokens until we reach it.
5444 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005445 ? clang_getNullCursor() : parent;
5446
5447 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5448
5449 // Avoid having the cursor of an expression "overwrite" the annotation of the
5450 // variable declaration that it belongs to.
5451 // This can happen for C++ constructor expressions whose range generally
5452 // include the variable declaration, e.g.:
5453 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005454 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005455 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005456 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005457 const unsigned I = NextToken();
5458 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5459 E->getLocStart() == D->getLocation() &&
5460 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005461 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005462 AdvanceToken();
5463 }
5464 }
5465 }
5466
5467 // Before recursing into the children keep some state that we are going
5468 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5469 // extra work after the child nodes are visited.
5470 // Note that we don't call VisitChildren here to avoid traversing statements
5471 // code-recursively which can blow the stack.
5472
5473 PostChildrenInfo Info;
5474 Info.Cursor = cursor;
5475 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005476 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005477 Info.BeforeChildrenTokenIdx = NextToken();
5478 PostChildrenInfos.push_back(Info);
5479
5480 return CXChildVisit_Recurse;
5481}
5482
5483bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5484 if (PostChildrenInfos.empty())
5485 return false;
5486 const PostChildrenInfo &Info = PostChildrenInfos.back();
5487 if (!clang_equalCursors(Info.Cursor, cursor))
5488 return false;
5489
5490 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5491 const unsigned AfterChildren = NextToken();
5492 SourceRange cursorRange = Info.CursorRange;
5493
5494 // Scan the tokens that are at the end of the cursor, but are not captured
5495 // but the child cursors.
5496 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5497
5498 // Scan the tokens that are at the beginning of the cursor, but are not
5499 // capture by the child cursors.
5500 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5501 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5502 break;
5503
5504 Cursors[I] = cursor;
5505 }
5506
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005507 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5508 // encountered the attribute cursor.
5509 if (clang_isAttribute(cursor.kind))
5510 TokIdx = Info.BeforeReachingCursorIdx;
5511
Guy Benyei11169dd2012-12-18 14:30:41 +00005512 PostChildrenInfos.pop_back();
5513 return false;
5514}
5515
5516static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5517 CXCursor parent,
5518 CXClientData client_data) {
5519 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5520}
5521
5522static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5523 CXClientData client_data) {
5524 return static_cast<AnnotateTokensWorker*>(client_data)->
5525 postVisitChildren(cursor);
5526}
5527
5528namespace {
5529
5530/// \brief Uses the macro expansions in the preprocessing record to find
5531/// and mark tokens that are macro arguments. This info is used by the
5532/// AnnotateTokensWorker.
5533class MarkMacroArgTokensVisitor {
5534 SourceManager &SM;
5535 CXToken *Tokens;
5536 unsigned NumTokens;
5537 unsigned CurIdx;
5538
5539public:
5540 MarkMacroArgTokensVisitor(SourceManager &SM,
5541 CXToken *tokens, unsigned numTokens)
5542 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5543
5544 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5545 if (cursor.kind != CXCursor_MacroExpansion)
5546 return CXChildVisit_Continue;
5547
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005548 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005549 if (macroRange.getBegin() == macroRange.getEnd())
5550 return CXChildVisit_Continue; // it's not a function macro.
5551
5552 for (; CurIdx < NumTokens; ++CurIdx) {
5553 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5554 macroRange.getBegin()))
5555 break;
5556 }
5557
5558 if (CurIdx == NumTokens)
5559 return CXChildVisit_Break;
5560
5561 for (; CurIdx < NumTokens; ++CurIdx) {
5562 SourceLocation tokLoc = getTokenLoc(CurIdx);
5563 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5564 break;
5565
5566 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5567 }
5568
5569 if (CurIdx == NumTokens)
5570 return CXChildVisit_Break;
5571
5572 return CXChildVisit_Continue;
5573 }
5574
5575private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005576 CXToken &getTok(unsigned Idx) {
5577 assert(Idx < NumTokens);
5578 return Tokens[Idx];
5579 }
5580 const CXToken &getTok(unsigned Idx) const {
5581 assert(Idx < NumTokens);
5582 return Tokens[Idx];
5583 }
5584
Guy Benyei11169dd2012-12-18 14:30:41 +00005585 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005586 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005587 }
5588
5589 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5590 // The third field is reserved and currently not used. Use it here
5591 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005592 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005593 }
5594};
5595
5596} // end anonymous namespace
5597
5598static CXChildVisitResult
5599MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5600 CXClientData client_data) {
5601 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5602 parent);
5603}
5604
5605namespace {
5606 struct clang_annotateTokens_Data {
5607 CXTranslationUnit TU;
5608 ASTUnit *CXXUnit;
5609 CXToken *Tokens;
5610 unsigned NumTokens;
5611 CXCursor *Cursors;
5612 };
5613}
5614
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005615/// \brief Used by \c annotatePreprocessorTokens.
5616/// \returns true if lexing was finished, false otherwise.
5617static bool lexNext(Lexer &Lex, Token &Tok,
5618 unsigned &NextIdx, unsigned NumTokens) {
5619 if (NextIdx >= NumTokens)
5620 return true;
5621
5622 ++NextIdx;
5623 Lex.LexFromRawLexer(Tok);
5624 if (Tok.is(tok::eof))
5625 return true;
5626
5627 return false;
5628}
5629
Guy Benyei11169dd2012-12-18 14:30:41 +00005630static void annotatePreprocessorTokens(CXTranslationUnit TU,
5631 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005632 CXCursor *Cursors,
5633 CXToken *Tokens,
5634 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005635 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005636
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005637 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005638 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5639 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005640 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005641 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005642 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005643
5644 if (BeginLocInfo.first != EndLocInfo.first)
5645 return;
5646
5647 StringRef Buffer;
5648 bool Invalid = false;
5649 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5650 if (Buffer.empty() || Invalid)
5651 return;
5652
5653 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5654 CXXUnit->getASTContext().getLangOpts(),
5655 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5656 Buffer.end());
5657 Lex.SetCommentRetentionState(true);
5658
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005659 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005660 // Lex tokens in raw mode until we hit the end of the range, to avoid
5661 // entering #includes or expanding macros.
5662 while (true) {
5663 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005664 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5665 break;
5666 unsigned TokIdx = NextIdx-1;
5667 assert(Tok.getLocation() ==
5668 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005669
5670 reprocess:
5671 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005672 // We have found a preprocessing directive. Annotate the tokens
5673 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005674 //
5675 // FIXME: Some simple tests here could identify macro definitions and
5676 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005677
5678 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005679 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5680 break;
5681
5682 MacroInfo *MI = 0;
5683 if (Tok.is(tok::raw_identifier) &&
5684 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5685 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5686 break;
5687
5688 if (Tok.is(tok::raw_identifier)) {
5689 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5690 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5691 SourceLocation MappedTokLoc =
5692 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5693 MI = getMacroInfo(II, MappedTokLoc, TU);
5694 }
5695 }
5696
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005697 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005698 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005699 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5700 finished = true;
5701 break;
5702 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005703 // If we are in a macro definition, check if the token was ever a
5704 // macro name and annotate it if that's the case.
5705 if (MI) {
5706 SourceLocation SaveLoc = Tok.getLocation();
5707 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5708 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5709 Tok.setLocation(SaveLoc);
5710 if (MacroDef)
5711 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5712 Tok.getLocation(), TU);
5713 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005714 } while (!Tok.isAtStartOfLine());
5715
5716 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5717 assert(TokIdx <= LastIdx);
5718 SourceLocation EndLoc =
5719 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5720 CXCursor Cursor =
5721 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5722
5723 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005724 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005725
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005726 if (finished)
5727 break;
5728 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005729 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005730 }
5731}
5732
5733// This gets run a separate thread to avoid stack blowout.
5734static void clang_annotateTokensImpl(void *UserData) {
5735 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5736 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5737 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5738 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5739 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5740
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005741 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005742 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5743 setThreadBackgroundPriority();
5744
5745 // Determine the region of interest, which contains all of the tokens.
5746 SourceRange RegionOfInterest;
5747 RegionOfInterest.setBegin(
5748 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5749 RegionOfInterest.setEnd(
5750 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5751 Tokens[NumTokens-1])));
5752
Guy Benyei11169dd2012-12-18 14:30:41 +00005753 // Relex the tokens within the source range to look for preprocessing
5754 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005755 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005756
5757 // If begin location points inside a macro argument, set it to the expansion
5758 // location so we can have the full context when annotating semantically.
5759 {
5760 SourceManager &SM = CXXUnit->getSourceManager();
5761 SourceLocation Loc =
5762 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5763 if (Loc.isMacroID())
5764 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5765 }
5766
Guy Benyei11169dd2012-12-18 14:30:41 +00005767 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5768 // Search and mark tokens that are macro argument expansions.
5769 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5770 Tokens, NumTokens);
5771 CursorVisitor MacroArgMarker(TU,
5772 MarkMacroArgTokensVisitorDelegate, &Visitor,
5773 /*VisitPreprocessorLast=*/true,
5774 /*VisitIncludedEntities=*/false,
5775 RegionOfInterest);
5776 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5777 }
5778
5779 // Annotate all of the source locations in the region of interest that map to
5780 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005781 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005782
5783 // FIXME: We use a ridiculous stack size here because the data-recursion
5784 // algorithm uses a large stack frame than the non-data recursive version,
5785 // and AnnotationTokensWorker currently transforms the data-recursion
5786 // algorithm back into a traditional recursion by explicitly calling
5787 // VisitChildren(). We will need to remove this explicit recursive call.
5788 W.AnnotateTokens();
5789
5790 // If we ran into any entities that involve context-sensitive keywords,
5791 // take another pass through the tokens to mark them as such.
5792 if (W.hasContextSensitiveKeywords()) {
5793 for (unsigned I = 0; I != NumTokens; ++I) {
5794 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5795 continue;
5796
5797 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5798 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005799 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005800 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5801 if (Property->getPropertyAttributesAsWritten() != 0 &&
5802 llvm::StringSwitch<bool>(II->getName())
5803 .Case("readonly", true)
5804 .Case("assign", true)
5805 .Case("unsafe_unretained", true)
5806 .Case("readwrite", true)
5807 .Case("retain", true)
5808 .Case("copy", true)
5809 .Case("nonatomic", true)
5810 .Case("atomic", true)
5811 .Case("getter", true)
5812 .Case("setter", true)
5813 .Case("strong", true)
5814 .Case("weak", true)
5815 .Default(false))
5816 Tokens[I].int_data[0] = CXToken_Keyword;
5817 }
5818 continue;
5819 }
5820
5821 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5822 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5823 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5824 if (llvm::StringSwitch<bool>(II->getName())
5825 .Case("in", true)
5826 .Case("out", true)
5827 .Case("inout", true)
5828 .Case("oneway", true)
5829 .Case("bycopy", true)
5830 .Case("byref", true)
5831 .Default(false))
5832 Tokens[I].int_data[0] = CXToken_Keyword;
5833 continue;
5834 }
5835
5836 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5837 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5838 Tokens[I].int_data[0] = CXToken_Keyword;
5839 continue;
5840 }
5841 }
5842 }
5843}
5844
5845extern "C" {
5846
5847void clang_annotateTokens(CXTranslationUnit TU,
5848 CXToken *Tokens, unsigned NumTokens,
5849 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005850 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005851 LOG_BAD_TU(TU);
5852 return;
5853 }
5854 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005855 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005856 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005857 }
5858
5859 LOG_FUNC_SECTION {
5860 *Log << TU << ' ';
5861 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5862 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5863 *Log << clang_getRange(bloc, eloc);
5864 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005865
5866 // Any token we don't specifically annotate will have a NULL cursor.
5867 CXCursor C = clang_getNullCursor();
5868 for (unsigned I = 0; I != NumTokens; ++I)
5869 Cursors[I] = C;
5870
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005871 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005872 if (!CXXUnit)
5873 return;
5874
5875 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5876
5877 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5878 llvm::CrashRecoveryContext CRC;
5879 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5880 GetSafetyThreadStackSize() * 2)) {
5881 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5882 }
5883}
5884
5885} // end: extern "C"
5886
5887//===----------------------------------------------------------------------===//
5888// Operations for querying linkage of a cursor.
5889//===----------------------------------------------------------------------===//
5890
5891extern "C" {
5892CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5893 if (!clang_isDeclaration(cursor.kind))
5894 return CXLinkage_Invalid;
5895
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005896 const Decl *D = cxcursor::getCursorDecl(cursor);
5897 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005898 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005899 case NoLinkage:
5900 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005901 case InternalLinkage: return CXLinkage_Internal;
5902 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5903 case ExternalLinkage: return CXLinkage_External;
5904 };
5905
5906 return CXLinkage_Invalid;
5907}
5908} // end: extern "C"
5909
5910//===----------------------------------------------------------------------===//
5911// Operations for querying language of a cursor.
5912//===----------------------------------------------------------------------===//
5913
5914static CXLanguageKind getDeclLanguage(const Decl *D) {
5915 if (!D)
5916 return CXLanguage_C;
5917
5918 switch (D->getKind()) {
5919 default:
5920 break;
5921 case Decl::ImplicitParam:
5922 case Decl::ObjCAtDefsField:
5923 case Decl::ObjCCategory:
5924 case Decl::ObjCCategoryImpl:
5925 case Decl::ObjCCompatibleAlias:
5926 case Decl::ObjCImplementation:
5927 case Decl::ObjCInterface:
5928 case Decl::ObjCIvar:
5929 case Decl::ObjCMethod:
5930 case Decl::ObjCProperty:
5931 case Decl::ObjCPropertyImpl:
5932 case Decl::ObjCProtocol:
5933 return CXLanguage_ObjC;
5934 case Decl::CXXConstructor:
5935 case Decl::CXXConversion:
5936 case Decl::CXXDestructor:
5937 case Decl::CXXMethod:
5938 case Decl::CXXRecord:
5939 case Decl::ClassTemplate:
5940 case Decl::ClassTemplatePartialSpecialization:
5941 case Decl::ClassTemplateSpecialization:
5942 case Decl::Friend:
5943 case Decl::FriendTemplate:
5944 case Decl::FunctionTemplate:
5945 case Decl::LinkageSpec:
5946 case Decl::Namespace:
5947 case Decl::NamespaceAlias:
5948 case Decl::NonTypeTemplateParm:
5949 case Decl::StaticAssert:
5950 case Decl::TemplateTemplateParm:
5951 case Decl::TemplateTypeParm:
5952 case Decl::UnresolvedUsingTypename:
5953 case Decl::UnresolvedUsingValue:
5954 case Decl::Using:
5955 case Decl::UsingDirective:
5956 case Decl::UsingShadow:
5957 return CXLanguage_CPlusPlus;
5958 }
5959
5960 return CXLanguage_C;
5961}
5962
5963extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005964
5965static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5966 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5967 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005968
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005969 switch (D->getAvailability()) {
5970 case AR_Available:
5971 case AR_NotYetIntroduced:
5972 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005973 return getCursorAvailabilityForDecl(
5974 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005975 return CXAvailability_Available;
5976
5977 case AR_Deprecated:
5978 return CXAvailability_Deprecated;
5979
5980 case AR_Unavailable:
5981 return CXAvailability_NotAvailable;
5982 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005983
5984 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005985}
5986
Guy Benyei11169dd2012-12-18 14:30:41 +00005987enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5988 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005989 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5990 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005991
5992 return CXAvailability_Available;
5993}
5994
5995static CXVersion convertVersion(VersionTuple In) {
5996 CXVersion Out = { -1, -1, -1 };
5997 if (In.empty())
5998 return Out;
5999
6000 Out.Major = In.getMajor();
6001
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006002 Optional<unsigned> Minor = In.getMinor();
6003 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006004 Out.Minor = *Minor;
6005 else
6006 return Out;
6007
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006008 Optional<unsigned> Subminor = In.getSubminor();
6009 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006010 Out.Subminor = *Subminor;
6011
6012 return Out;
6013}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006014
6015static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6016 int *always_deprecated,
6017 CXString *deprecated_message,
6018 int *always_unavailable,
6019 CXString *unavailable_message,
6020 CXPlatformAvailability *availability,
6021 int availability_size) {
6022 bool HadAvailAttr = false;
6023 int N = 0;
6024 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
6025 ++A) {
6026 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
6027 HadAvailAttr = true;
6028 if (always_deprecated)
6029 *always_deprecated = 1;
6030 if (deprecated_message)
6031 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
6032 continue;
6033 }
6034
6035 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
6036 HadAvailAttr = true;
6037 if (always_unavailable)
6038 *always_unavailable = 1;
6039 if (unavailable_message) {
6040 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6041 }
6042 continue;
6043 }
6044
6045 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
6046 HadAvailAttr = true;
6047 if (N < availability_size) {
6048 availability[N].Platform
6049 = cxstring::createDup(Avail->getPlatform()->getName());
6050 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6051 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6052 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6053 availability[N].Unavailable = Avail->getUnavailable();
6054 availability[N].Message = cxstring::createDup(Avail->getMessage());
6055 }
6056 ++N;
6057 }
6058 }
6059
6060 if (!HadAvailAttr)
6061 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6062 return getCursorPlatformAvailabilityForDecl(
6063 cast<Decl>(EnumConst->getDeclContext()),
6064 always_deprecated,
6065 deprecated_message,
6066 always_unavailable,
6067 unavailable_message,
6068 availability,
6069 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006070
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006071 return N;
6072}
6073
Guy Benyei11169dd2012-12-18 14:30:41 +00006074int clang_getCursorPlatformAvailability(CXCursor cursor,
6075 int *always_deprecated,
6076 CXString *deprecated_message,
6077 int *always_unavailable,
6078 CXString *unavailable_message,
6079 CXPlatformAvailability *availability,
6080 int availability_size) {
6081 if (always_deprecated)
6082 *always_deprecated = 0;
6083 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006084 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006085 if (always_unavailable)
6086 *always_unavailable = 0;
6087 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006088 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006089
Guy Benyei11169dd2012-12-18 14:30:41 +00006090 if (!clang_isDeclaration(cursor.kind))
6091 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006092
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006093 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006094 if (!D)
6095 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006096
6097 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6098 deprecated_message,
6099 always_unavailable,
6100 unavailable_message,
6101 availability,
6102 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006103}
6104
6105void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6106 clang_disposeString(availability->Platform);
6107 clang_disposeString(availability->Message);
6108}
6109
6110CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6111 if (clang_isDeclaration(cursor.kind))
6112 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6113
6114 return CXLanguage_Invalid;
6115}
6116
6117 /// \brief If the given cursor is the "templated" declaration
6118 /// descibing a class or function template, return the class or
6119 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006120static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006121 if (!D)
6122 return 0;
6123
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006124 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006125 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6126 return FunTmpl;
6127
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006128 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006129 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6130 return ClassTmpl;
6131
6132 return D;
6133}
6134
6135CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6136 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006137 if (const Decl *D = getCursorDecl(cursor)) {
6138 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006139 if (!DC)
6140 return clang_getNullCursor();
6141
6142 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6143 getCursorTU(cursor));
6144 }
6145 }
6146
6147 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006148 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006149 return MakeCXCursor(D, getCursorTU(cursor));
6150 }
6151
6152 return clang_getNullCursor();
6153}
6154
6155CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6156 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006157 if (const Decl *D = getCursorDecl(cursor)) {
6158 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006159 if (!DC)
6160 return clang_getNullCursor();
6161
6162 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6163 getCursorTU(cursor));
6164 }
6165 }
6166
6167 // FIXME: Note that we can't easily compute the lexical context of a
6168 // statement or expression, so we return nothing.
6169 return clang_getNullCursor();
6170}
6171
6172CXFile clang_getIncludedFile(CXCursor cursor) {
6173 if (cursor.kind != CXCursor_InclusionDirective)
6174 return 0;
6175
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006176 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006177 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006178}
6179
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006180unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6181 if (C.kind != CXCursor_ObjCPropertyDecl)
6182 return CXObjCPropertyAttr_noattr;
6183
6184 unsigned Result = CXObjCPropertyAttr_noattr;
6185 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6186 ObjCPropertyDecl::PropertyAttributeKind Attr =
6187 PD->getPropertyAttributesAsWritten();
6188
6189#define SET_CXOBJCPROP_ATTR(A) \
6190 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6191 Result |= CXObjCPropertyAttr_##A
6192 SET_CXOBJCPROP_ATTR(readonly);
6193 SET_CXOBJCPROP_ATTR(getter);
6194 SET_CXOBJCPROP_ATTR(assign);
6195 SET_CXOBJCPROP_ATTR(readwrite);
6196 SET_CXOBJCPROP_ATTR(retain);
6197 SET_CXOBJCPROP_ATTR(copy);
6198 SET_CXOBJCPROP_ATTR(nonatomic);
6199 SET_CXOBJCPROP_ATTR(setter);
6200 SET_CXOBJCPROP_ATTR(atomic);
6201 SET_CXOBJCPROP_ATTR(weak);
6202 SET_CXOBJCPROP_ATTR(strong);
6203 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6204#undef SET_CXOBJCPROP_ATTR
6205
6206 return Result;
6207}
6208
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006209unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6210 if (!clang_isDeclaration(C.kind))
6211 return CXObjCDeclQualifier_None;
6212
6213 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6214 const Decl *D = getCursorDecl(C);
6215 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6216 QT = MD->getObjCDeclQualifier();
6217 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6218 QT = PD->getObjCDeclQualifier();
6219 if (QT == Decl::OBJC_TQ_None)
6220 return CXObjCDeclQualifier_None;
6221
6222 unsigned Result = CXObjCDeclQualifier_None;
6223 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6224 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6225 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6226 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6227 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6228 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6229
6230 return Result;
6231}
6232
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006233unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6234 if (!clang_isDeclaration(C.kind))
6235 return 0;
6236
6237 const Decl *D = getCursorDecl(C);
6238 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6239 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6240 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6241 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6242
6243 return 0;
6244}
6245
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006246unsigned clang_Cursor_isVariadic(CXCursor C) {
6247 if (!clang_isDeclaration(C.kind))
6248 return 0;
6249
6250 const Decl *D = getCursorDecl(C);
6251 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6252 return FD->isVariadic();
6253 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6254 return MD->isVariadic();
6255
6256 return 0;
6257}
6258
Guy Benyei11169dd2012-12-18 14:30:41 +00006259CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6260 if (!clang_isDeclaration(C.kind))
6261 return clang_getNullRange();
6262
6263 const Decl *D = getCursorDecl(C);
6264 ASTContext &Context = getCursorContext(C);
6265 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6266 if (!RC)
6267 return clang_getNullRange();
6268
6269 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6270}
6271
6272CXString clang_Cursor_getRawCommentText(CXCursor C) {
6273 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006274 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006275
6276 const Decl *D = getCursorDecl(C);
6277 ASTContext &Context = getCursorContext(C);
6278 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6279 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6280 StringRef();
6281
6282 // Don't duplicate the string because RawText points directly into source
6283 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006284 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006285}
6286
6287CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6288 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006289 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006290
6291 const Decl *D = getCursorDecl(C);
6292 const ASTContext &Context = getCursorContext(C);
6293 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6294
6295 if (RC) {
6296 StringRef BriefText = RC->getBriefText(Context);
6297
6298 // Don't duplicate the string because RawComment ensures that this memory
6299 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006300 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006301 }
6302
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006303 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006304}
6305
6306CXComment clang_Cursor_getParsedComment(CXCursor C) {
6307 if (!clang_isDeclaration(C.kind))
6308 return cxcomment::createCXComment(NULL, NULL);
6309
6310 const Decl *D = getCursorDecl(C);
6311 const ASTContext &Context = getCursorContext(C);
6312 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6313
6314 return cxcomment::createCXComment(FC, getCursorTU(C));
6315}
6316
6317CXModule clang_Cursor_getModule(CXCursor C) {
6318 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006319 if (const ImportDecl *ImportD =
6320 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006321 return ImportD->getImportedModule();
6322 }
6323
6324 return 0;
6325}
6326
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006327CXFile clang_Module_getASTFile(CXModule CXMod) {
6328 if (!CXMod)
6329 return 0;
6330 Module *Mod = static_cast<Module*>(CXMod);
6331 return const_cast<FileEntry *>(Mod->getASTFile());
6332}
6333
Guy Benyei11169dd2012-12-18 14:30:41 +00006334CXModule clang_Module_getParent(CXModule CXMod) {
6335 if (!CXMod)
6336 return 0;
6337 Module *Mod = static_cast<Module*>(CXMod);
6338 return Mod->Parent;
6339}
6340
6341CXString clang_Module_getName(CXModule CXMod) {
6342 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006343 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006344 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006345 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006346}
6347
6348CXString clang_Module_getFullName(CXModule CXMod) {
6349 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006350 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006351 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006352 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006353}
6354
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006355unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6356 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006357 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006358 LOG_BAD_TU(TU);
6359 return 0;
6360 }
6361 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006362 return 0;
6363 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006364 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6365 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6366 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006367}
6368
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006369CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6370 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006371 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006372 LOG_BAD_TU(TU);
6373 return 0;
6374 }
6375 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006376 return 0;
6377 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006378 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006379
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006380 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6381 if (Index < TopHeaders.size())
6382 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006383
6384 return 0;
6385}
6386
6387} // end: extern "C"
6388
6389//===----------------------------------------------------------------------===//
6390// C++ AST instrospection.
6391//===----------------------------------------------------------------------===//
6392
6393extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006394unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6395 if (!clang_isDeclaration(C.kind))
6396 return 0;
6397
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006398 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006399 const CXXMethodDecl *Method =
6400 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006401 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6402}
6403
Guy Benyei11169dd2012-12-18 14:30:41 +00006404unsigned clang_CXXMethod_isStatic(CXCursor C) {
6405 if (!clang_isDeclaration(C.kind))
6406 return 0;
6407
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006408 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006409 const CXXMethodDecl *Method =
6410 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006411 return (Method && Method->isStatic()) ? 1 : 0;
6412}
6413
6414unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6415 if (!clang_isDeclaration(C.kind))
6416 return 0;
6417
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006418 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006419 const CXXMethodDecl *Method =
6420 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006421 return (Method && Method->isVirtual()) ? 1 : 0;
6422}
6423} // end: extern "C"
6424
6425//===----------------------------------------------------------------------===//
6426// Attribute introspection.
6427//===----------------------------------------------------------------------===//
6428
6429extern "C" {
6430CXType clang_getIBOutletCollectionType(CXCursor C) {
6431 if (C.kind != CXCursor_IBOutletCollectionAttr)
6432 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6433
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006434 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006435 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6436
6437 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6438}
6439} // end: extern "C"
6440
6441//===----------------------------------------------------------------------===//
6442// Inspecting memory usage.
6443//===----------------------------------------------------------------------===//
6444
6445typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6446
6447static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6448 enum CXTUResourceUsageKind k,
6449 unsigned long amount) {
6450 CXTUResourceUsageEntry entry = { k, amount };
6451 entries.push_back(entry);
6452}
6453
6454extern "C" {
6455
6456const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6457 const char *str = "";
6458 switch (kind) {
6459 case CXTUResourceUsage_AST:
6460 str = "ASTContext: expressions, declarations, and types";
6461 break;
6462 case CXTUResourceUsage_Identifiers:
6463 str = "ASTContext: identifiers";
6464 break;
6465 case CXTUResourceUsage_Selectors:
6466 str = "ASTContext: selectors";
6467 break;
6468 case CXTUResourceUsage_GlobalCompletionResults:
6469 str = "Code completion: cached global results";
6470 break;
6471 case CXTUResourceUsage_SourceManagerContentCache:
6472 str = "SourceManager: content cache allocator";
6473 break;
6474 case CXTUResourceUsage_AST_SideTables:
6475 str = "ASTContext: side tables";
6476 break;
6477 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6478 str = "SourceManager: malloc'ed memory buffers";
6479 break;
6480 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6481 str = "SourceManager: mmap'ed memory buffers";
6482 break;
6483 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6484 str = "ExternalASTSource: malloc'ed memory buffers";
6485 break;
6486 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6487 str = "ExternalASTSource: mmap'ed memory buffers";
6488 break;
6489 case CXTUResourceUsage_Preprocessor:
6490 str = "Preprocessor: malloc'ed memory";
6491 break;
6492 case CXTUResourceUsage_PreprocessingRecord:
6493 str = "Preprocessor: PreprocessingRecord";
6494 break;
6495 case CXTUResourceUsage_SourceManager_DataStructures:
6496 str = "SourceManager: data structures and tables";
6497 break;
6498 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6499 str = "Preprocessor: header search tables";
6500 break;
6501 }
6502 return str;
6503}
6504
6505CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006506 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006507 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006508 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6509 return usage;
6510 }
6511
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006512 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006513 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6514 ASTContext &astContext = astUnit->getASTContext();
6515
6516 // How much memory is used by AST nodes and types?
6517 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6518 (unsigned long) astContext.getASTAllocatedMemory());
6519
6520 // How much memory is used by identifiers?
6521 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6522 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6523
6524 // How much memory is used for selectors?
6525 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6526 (unsigned long) astContext.Selectors.getTotalMemory());
6527
6528 // How much memory is used by ASTContext's side tables?
6529 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6530 (unsigned long) astContext.getSideTableAllocatedMemory());
6531
6532 // How much memory is used for caching global code completion results?
6533 unsigned long completionBytes = 0;
6534 if (GlobalCodeCompletionAllocator *completionAllocator =
6535 astUnit->getCachedCompletionAllocator().getPtr()) {
6536 completionBytes = completionAllocator->getTotalMemory();
6537 }
6538 createCXTUResourceUsageEntry(*entries,
6539 CXTUResourceUsage_GlobalCompletionResults,
6540 completionBytes);
6541
6542 // How much memory is being used by SourceManager's content cache?
6543 createCXTUResourceUsageEntry(*entries,
6544 CXTUResourceUsage_SourceManagerContentCache,
6545 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6546
6547 // How much memory is being used by the MemoryBuffer's in SourceManager?
6548 const SourceManager::MemoryBufferSizes &srcBufs =
6549 astUnit->getSourceManager().getMemoryBufferSizes();
6550
6551 createCXTUResourceUsageEntry(*entries,
6552 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6553 (unsigned long) srcBufs.malloc_bytes);
6554 createCXTUResourceUsageEntry(*entries,
6555 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6556 (unsigned long) srcBufs.mmap_bytes);
6557 createCXTUResourceUsageEntry(*entries,
6558 CXTUResourceUsage_SourceManager_DataStructures,
6559 (unsigned long) astContext.getSourceManager()
6560 .getDataStructureSizes());
6561
6562 // How much memory is being used by the ExternalASTSource?
6563 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6564 const ExternalASTSource::MemoryBufferSizes &sizes =
6565 esrc->getMemoryBufferSizes();
6566
6567 createCXTUResourceUsageEntry(*entries,
6568 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6569 (unsigned long) sizes.malloc_bytes);
6570 createCXTUResourceUsageEntry(*entries,
6571 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6572 (unsigned long) sizes.mmap_bytes);
6573 }
6574
6575 // How much memory is being used by the Preprocessor?
6576 Preprocessor &pp = astUnit->getPreprocessor();
6577 createCXTUResourceUsageEntry(*entries,
6578 CXTUResourceUsage_Preprocessor,
6579 pp.getTotalMemory());
6580
6581 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6582 createCXTUResourceUsageEntry(*entries,
6583 CXTUResourceUsage_PreprocessingRecord,
6584 pRec->getTotalMemory());
6585 }
6586
6587 createCXTUResourceUsageEntry(*entries,
6588 CXTUResourceUsage_Preprocessor_HeaderSearch,
6589 pp.getHeaderSearchInfo().getTotalMemory());
6590
6591 CXTUResourceUsage usage = { (void*) entries.get(),
6592 (unsigned) entries->size(),
6593 entries->size() ? &(*entries)[0] : 0 };
6594 entries.take();
6595 return usage;
6596}
6597
6598void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6599 if (usage.data)
6600 delete (MemUsageEntries*) usage.data;
6601}
6602
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006603CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6604 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006605 skipped->count = 0;
6606 skipped->ranges = 0;
6607
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006608 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006609 LOG_BAD_TU(TU);
6610 return skipped;
6611 }
6612
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006613 if (!file)
6614 return skipped;
6615
6616 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6617 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6618 if (!ppRec)
6619 return skipped;
6620
6621 ASTContext &Ctx = astUnit->getASTContext();
6622 SourceManager &sm = Ctx.getSourceManager();
6623 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6624 FileID wantedFileID = sm.translateFile(fileEntry);
6625
6626 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6627 std::vector<SourceRange> wantedRanges;
6628 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6629 i != ei; ++i) {
6630 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6631 wantedRanges.push_back(*i);
6632 }
6633
6634 skipped->count = wantedRanges.size();
6635 skipped->ranges = new CXSourceRange[skipped->count];
6636 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6637 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6638
6639 return skipped;
6640}
6641
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006642void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6643 if (ranges) {
6644 delete[] ranges->ranges;
6645 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006646 }
6647}
6648
Guy Benyei11169dd2012-12-18 14:30:41 +00006649} // end extern "C"
6650
6651void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6652 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6653 for (unsigned I = 0; I != Usage.numEntries; ++I)
6654 fprintf(stderr, " %s: %lu\n",
6655 clang_getTUResourceUsageName(Usage.entries[I].kind),
6656 Usage.entries[I].amount);
6657
6658 clang_disposeCXTUResourceUsage(Usage);
6659}
6660
6661//===----------------------------------------------------------------------===//
6662// Misc. utility functions.
6663//===----------------------------------------------------------------------===//
6664
6665/// Default to using an 8 MB stack size on "safety" threads.
6666static unsigned SafetyStackThreadSize = 8 << 20;
6667
6668namespace clang {
6669
6670bool RunSafely(llvm::CrashRecoveryContext &CRC,
6671 void (*Fn)(void*), void *UserData,
6672 unsigned Size) {
6673 if (!Size)
6674 Size = GetSafetyThreadStackSize();
6675 if (Size)
6676 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6677 return CRC.RunSafely(Fn, UserData);
6678}
6679
6680unsigned GetSafetyThreadStackSize() {
6681 return SafetyStackThreadSize;
6682}
6683
6684void SetSafetyThreadStackSize(unsigned Value) {
6685 SafetyStackThreadSize = Value;
6686}
6687
6688}
6689
6690void clang::setThreadBackgroundPriority() {
6691 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6692 return;
6693
6694 // FIXME: Move to llvm/Support and make it cross-platform.
6695#ifdef __APPLE__
6696 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6697#endif
6698}
6699
6700void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6701 if (!Unit)
6702 return;
6703
6704 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6705 DEnd = Unit->stored_diag_end();
6706 D != DEnd; ++D) {
6707 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6708 CXString Msg = clang_formatDiagnostic(&Diag,
6709 clang_defaultDiagnosticDisplayOptions());
6710 fprintf(stderr, "%s\n", clang_getCString(Msg));
6711 clang_disposeString(Msg);
6712 }
6713#ifdef LLVM_ON_WIN32
6714 // On Windows, force a flush, since there may be multiple copies of
6715 // stderr and stdout in the file system, all with different buffers
6716 // but writing to the same device.
6717 fflush(stderr);
6718#endif
6719}
6720
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006721MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6722 SourceLocation MacroDefLoc,
6723 CXTranslationUnit TU){
6724 if (MacroDefLoc.isInvalid() || !TU)
6725 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006726 if (!II.hadMacroDefinition())
6727 return 0;
6728
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006729 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006730 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006731 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006732 if (MD) {
6733 for (MacroDirective::DefInfo
6734 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6735 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6736 return Def.getMacroInfo();
6737 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006738 }
6739
6740 return 0;
6741}
6742
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006743const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6744 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006745 if (!MacroDef || !TU)
6746 return 0;
6747 const IdentifierInfo *II = MacroDef->getName();
6748 if (!II)
6749 return 0;
6750
6751 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6752}
6753
6754MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6755 const Token &Tok,
6756 CXTranslationUnit TU) {
6757 if (!MI || !TU)
6758 return 0;
6759 if (Tok.isNot(tok::raw_identifier))
6760 return 0;
6761
6762 if (MI->getNumTokens() == 0)
6763 return 0;
6764 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6765 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006766 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006767
6768 // Check that the token is inside the definition and not its argument list.
6769 SourceManager &SM = Unit->getSourceManager();
6770 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6771 return 0;
6772 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6773 return 0;
6774
6775 Preprocessor &PP = Unit->getPreprocessor();
6776 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6777 if (!PPRec)
6778 return 0;
6779
6780 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6781 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6782 if (!II.hadMacroDefinition())
6783 return 0;
6784
6785 // Check that the identifier is not one of the macro arguments.
6786 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6787 return 0;
6788
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006789 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6790 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006791 return 0;
6792
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006793 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006794}
6795
6796MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6797 SourceLocation Loc,
6798 CXTranslationUnit TU) {
6799 if (Loc.isInvalid() || !MI || !TU)
6800 return 0;
6801
6802 if (MI->getNumTokens() == 0)
6803 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006804 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006805 Preprocessor &PP = Unit->getPreprocessor();
6806 if (!PP.getPreprocessingRecord())
6807 return 0;
6808 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6809 Token Tok;
6810 if (PP.getRawToken(Loc, Tok))
6811 return 0;
6812
6813 return checkForMacroInMacroDefinition(MI, Tok, TU);
6814}
6815
Guy Benyei11169dd2012-12-18 14:30:41 +00006816extern "C" {
6817
6818CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006819 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006820}
6821
6822} // end: extern "C"
6823
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006824Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6825 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006826 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006827 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006828 if (Unit->isMainFileAST())
6829 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006830 return *this;
6831 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006832 } else {
6833 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006834 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006835 return *this;
6836}
6837
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006838Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6839 *this << FE->getName();
6840 return *this;
6841}
6842
6843Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6844 CXString cursorName = clang_getCursorDisplayName(cursor);
6845 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6846 clang_disposeString(cursorName);
6847 return *this;
6848}
6849
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006850Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6851 CXFile File;
6852 unsigned Line, Column;
6853 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6854 CXString FileName = clang_getFileName(File);
6855 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6856 clang_disposeString(FileName);
6857 return *this;
6858}
6859
6860Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6861 CXSourceLocation BLoc = clang_getRangeStart(range);
6862 CXSourceLocation ELoc = clang_getRangeEnd(range);
6863
6864 CXFile BFile;
6865 unsigned BLine, BColumn;
6866 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6867
6868 CXFile EFile;
6869 unsigned ELine, EColumn;
6870 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6871
6872 CXString BFileName = clang_getFileName(BFile);
6873 if (BFile == EFile) {
6874 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6875 BLine, BColumn, ELine, EColumn);
6876 } else {
6877 CXString EFileName = clang_getFileName(EFile);
6878 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6879 BLine, BColumn)
6880 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6881 ELine, EColumn);
6882 clang_disposeString(EFileName);
6883 }
6884 clang_disposeString(BFileName);
6885 return *this;
6886}
6887
6888Logger &cxindex::Logger::operator<<(CXString Str) {
6889 *this << clang_getCString(Str);
6890 return *this;
6891}
6892
6893Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6894 LogOS << Fmt;
6895 return *this;
6896}
6897
6898cxindex::Logger::~Logger() {
6899 LogOS.flush();
6900
6901 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6902
6903 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6904
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006905 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006906 OS << "[libclang:" << Name << ':';
6907
6908 // FIXME: Portability.
6909#if HAVE_PTHREAD_H && __APPLE__
6910 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6911 OS << tid << ':';
6912#endif
6913
6914 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6915 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6916 OS << Msg.str() << '\n';
6917
6918 if (Trace) {
6919 llvm::sys::PrintStackTrace(stderr);
6920 OS << "--------------------------------------------------\n";
6921 }
6922}