blob: dacd46e96fc42ac72ea78e093783d2e041100193 [file] [log] [blame]
Guy Benyei7f92f2d2012-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 Carruthb1ba0ef2013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei7f92f2d2012-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"
Fariborz Jahanian88b95212012-12-18 23:02:59 +000025#include "SimpleFormatContext.h"
Guy Benyei7f92f2d2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
28#include "clang/Basic/Version.h"
29#include "clang/Frontend/ASTUnit.h"
30#include "clang/Frontend/CompilerInstance.h"
31#include "clang/Frontend/FrontendDiagnostic.h"
32#include "clang/Lex/HeaderSearch.h"
33#include "clang/Lex/Lexer.h"
34#include "clang/Lex/PreprocessingRecord.h"
35#include "clang/Lex/Preprocessor.h"
36#include "llvm/ADT/Optional.h"
37#include "llvm/ADT/STLExtras.h"
38#include "llvm/ADT/StringSwitch.h"
Chandler Carruthb1ba0ef2013-01-19 08:09:44 +000039#include "llvm/Config/config.h"
Guy Benyei7f92f2d2012-12-18 14:30:41 +000040#include "llvm/Support/Compiler.h"
41#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruthb1ba0ef2013-01-19 08:09:44 +000042#include "llvm/Support/Format.h"
Guy Benyei7f92f2d2012-12-18 14:30:41 +000043#include "llvm/Support/MemoryBuffer.h"
44#include "llvm/Support/Mutex.h"
45#include "llvm/Support/PrettyStackTrace.h"
46#include "llvm/Support/Program.h"
47#include "llvm/Support/SaveAndRestore.h"
48#include "llvm/Support/Signals.h"
49#include "llvm/Support/Threading.h"
50#include "llvm/Support/Timer.h"
51#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +000052
53#if HAVE_PTHREAD_H
54#include <pthread.h>
55#endif
Guy Benyei7f92f2d2012-12-18 14:30:41 +000056
57using namespace clang;
58using namespace clang::cxcursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +000059using namespace clang::cxtu;
60using namespace clang::cxindex;
61
Dmitri Gribenkoe42e5782013-01-26 21:32:42 +000062CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
63 if (!AU)
Guy Benyei7f92f2d2012-12-18 14:30:41 +000064 return 0;
65 CXTranslationUnit D = new CXTranslationUnitImpl();
66 D->CIdx = CIdx;
Dmitri Gribenkoe42e5782013-01-26 21:32:42 +000067 D->TheASTUnit = AU;
Dmitri Gribenkoaca3e562013-02-03 13:52:47 +000068 D->StringPool = new cxstring::CXStringPool();
Guy Benyei7f92f2d2012-12-18 14:30:41 +000069 D->Diagnostics = 0;
70 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Fariborz Jahanian88b95212012-12-18 23:02:59 +000071 D->FormatContext = 0;
72 D->FormatInMemoryUniqueId = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +000073 return D;
74}
75
76cxtu::CXTUOwner::~CXTUOwner() {
77 if (TU)
78 clang_disposeTranslationUnit(TU);
79}
80
81/// \brief Compare two source ranges to determine their relative position in
82/// the translation unit.
83static RangeComparisonResult RangeCompare(SourceManager &SM,
84 SourceRange R1,
85 SourceRange R2) {
86 assert(R1.isValid() && "First range is invalid?");
87 assert(R2.isValid() && "Second range is invalid?");
88 if (R1.getEnd() != R2.getBegin() &&
89 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
90 return RangeBefore;
91 if (R2.getEnd() != R1.getBegin() &&
92 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
93 return RangeAfter;
94 return RangeOverlap;
95}
96
97/// \brief Determine if a source location falls within, before, or after a
98/// a given source range.
99static RangeComparisonResult LocationCompare(SourceManager &SM,
100 SourceLocation L, SourceRange R) {
101 assert(R.isValid() && "First range is invalid?");
102 assert(L.isValid() && "Second range is invalid?");
103 if (L == R.getBegin() || L == R.getEnd())
104 return RangeOverlap;
105 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
106 return RangeBefore;
107 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
108 return RangeAfter;
109 return RangeOverlap;
110}
111
112/// \brief Translate a Clang source range into a CIndex source range.
113///
114/// Clang internally represents ranges where the end location points to the
115/// start of the token at the end. However, for external clients it is more
116/// useful to have a CXSourceRange be a proper half-open interval. This routine
117/// does the appropriate translation.
118CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
119 const LangOptions &LangOpts,
120 const CharSourceRange &R) {
121 // We want the last character in this location, so we will adjust the
122 // location accordingly.
123 SourceLocation EndLoc = R.getEnd();
124 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
125 EndLoc = SM.getExpansionRange(EndLoc).second;
126 if (R.isTokenRange() && !EndLoc.isInvalid()) {
127 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
128 SM, LangOpts);
129 EndLoc = EndLoc.getLocWithOffset(Length);
130 }
131
Bill Wendlingccdfdd72013-01-23 08:25:41 +0000132 CXSourceRange Result = {
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +0000133 { &SM, &LangOpts },
Bill Wendlingccdfdd72013-01-23 08:25:41 +0000134 R.getBegin().getRawEncoding(),
135 EndLoc.getRawEncoding()
136 };
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000137 return Result;
138}
139
140//===----------------------------------------------------------------------===//
141// Cursor visitor.
142//===----------------------------------------------------------------------===//
143
144static SourceRange getRawCursorExtent(CXCursor C);
145static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
146
147
148RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
149 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
150}
151
152/// \brief Visit the given cursor and, if requested by the visitor,
153/// its children.
154///
155/// \param Cursor the cursor to visit.
156///
157/// \param CheckedRegionOfInterest if true, then the caller already checked
158/// that this cursor is within the region of interest.
159///
160/// \returns true if the visitation should be aborted, false if it
161/// should continue.
162bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
163 if (clang_isInvalid(Cursor.kind))
164 return false;
165
166 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +0000167 const Decl *D = getCursorDecl(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000168 if (!D) {
169 assert(0 && "Invalid declaration cursor");
170 return true; // abort.
171 }
172
173 // Ignore implicit declarations, unless it's an objc method because
174 // currently we should report implicit methods for properties when indexing.
175 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
176 return false;
177 }
178
179 // If we have a range of interest, and this cursor doesn't intersect with it,
180 // we're done.
181 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
182 SourceRange Range = getRawCursorExtent(Cursor);
183 if (Range.isInvalid() || CompareRegionOfInterest(Range))
184 return false;
185 }
186
187 switch (Visitor(Cursor, Parent, ClientData)) {
188 case CXChildVisit_Break:
189 return true;
190
191 case CXChildVisit_Continue:
192 return false;
193
194 case CXChildVisit_Recurse: {
195 bool ret = VisitChildren(Cursor);
196 if (PostChildrenVisitor)
197 if (PostChildrenVisitor(Cursor, ClientData))
198 return true;
199 return ret;
200 }
201 }
202
203 llvm_unreachable("Invalid CXChildVisitResult!");
204}
205
206static bool visitPreprocessedEntitiesInRange(SourceRange R,
207 PreprocessingRecord &PPRec,
208 CursorVisitor &Visitor) {
209 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
210 FileID FID;
211
212 if (!Visitor.shouldVisitIncludedEntities()) {
213 // If the begin/end of the range lie in the same FileID, do the optimization
214 // where we skip preprocessed entities that do not come from the same FileID.
215 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
216 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
217 FID = FileID();
218 }
219
220 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
221 Entities = PPRec.getPreprocessedEntitiesInRange(R);
222 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
223 PPRec, FID);
224}
225
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000226bool CursorVisitor::visitFileRegion() {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000227 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000228 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000229
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000230 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000231 SourceManager &SM = Unit->getSourceManager();
232
233 std::pair<FileID, unsigned>
234 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
235 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
236
237 if (End.first != Begin.first) {
238 // If the end does not reside in the same file, try to recover by
239 // picking the end of the file of begin location.
240 End.first = Begin.first;
241 End.second = SM.getFileIDSize(Begin.first);
242 }
243
244 assert(Begin.first == End.first);
245 if (Begin.second > End.second)
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000246 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000247
248 FileID File = Begin.first;
249 unsigned Offset = Begin.second;
250 unsigned Length = End.second - Begin.second;
251
252 if (!VisitDeclsOnly && !VisitPreprocessorLast)
253 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000254 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000255
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000256 if (visitDeclsFromFileRegion(File, Offset, Length))
257 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000258
259 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000260 return visitPreprocessedEntitiesInRegion();
261
262 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000263}
264
265static bool isInLexicalContext(Decl *D, DeclContext *DC) {
266 if (!DC)
267 return false;
268
269 for (DeclContext *DeclDC = D->getLexicalDeclContext();
270 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
271 if (DeclDC == DC)
272 return true;
273 }
274 return false;
275}
276
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000277bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000278 unsigned Offset, unsigned Length) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000279 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000280 SourceManager &SM = Unit->getSourceManager();
281 SourceRange Range = RegionOfInterest;
282
283 SmallVector<Decl *, 16> Decls;
284 Unit->findFileRegionDecls(File, Offset, Length, Decls);
285
286 // If we didn't find any file level decls for the file, try looking at the
287 // file that it was included from.
288 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
289 bool Invalid = false;
290 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
291 if (Invalid)
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000292 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000293
294 SourceLocation Outer;
295 if (SLEntry.isFile())
296 Outer = SLEntry.getFile().getIncludeLoc();
297 else
298 Outer = SLEntry.getExpansion().getExpansionLocStart();
299 if (Outer.isInvalid())
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000300 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000301
302 llvm::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
303 Length = 0;
304 Unit->findFileRegionDecls(File, Offset, Length, Decls);
305 }
306
307 assert(!Decls.empty());
308
309 bool VisitedAtLeastOnce = false;
310 DeclContext *CurDC = 0;
311 SmallVector<Decl *, 16>::iterator DIt = Decls.begin();
312 for (SmallVector<Decl *, 16>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
313 Decl *D = *DIt;
314 if (D->getSourceRange().isInvalid())
315 continue;
316
317 if (isInLexicalContext(D, CurDC))
318 continue;
319
320 CurDC = dyn_cast<DeclContext>(D);
321
322 if (TagDecl *TD = dyn_cast<TagDecl>(D))
323 if (!TD->isFreeStanding())
324 continue;
325
326 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
327 if (CompRes == RangeBefore)
328 continue;
329 if (CompRes == RangeAfter)
330 break;
331
332 assert(CompRes == RangeOverlap);
333 VisitedAtLeastOnce = true;
334
335 if (isa<ObjCContainerDecl>(D)) {
336 FileDI_current = &DIt;
337 FileDE_current = DE;
338 } else {
339 FileDI_current = 0;
340 }
341
342 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000343 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000344 }
345
346 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000347 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000348
349 // No Decls overlapped with the range. Move up the lexical context until there
350 // is a context that contains the range or we reach the translation unit
351 // level.
352 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
353 : (*(DIt-1))->getLexicalDeclContext();
354
355 while (DC && !DC->isTranslationUnit()) {
356 Decl *D = cast<Decl>(DC);
357 SourceRange CurDeclRange = D->getSourceRange();
358 if (CurDeclRange.isInvalid())
359 break;
360
361 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000362 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
363 return true; // visitation break.
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000364 }
365
366 DC = D->getLexicalDeclContext();
367 }
Argyrios Kyrtzidis389dc562013-03-08 20:42:33 +0000368
369 return false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000370}
371
372bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
373 if (!AU->getPreprocessor().getPreprocessingRecord())
374 return false;
375
376 PreprocessingRecord &PPRec
377 = *AU->getPreprocessor().getPreprocessingRecord();
378 SourceManager &SM = AU->getSourceManager();
379
380 if (RegionOfInterest.isValid()) {
381 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
382 SourceLocation B = MappedRange.getBegin();
383 SourceLocation E = MappedRange.getEnd();
384
385 if (AU->isInPreambleFileID(B)) {
386 if (SM.isLoadedSourceLocation(E))
387 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
388 PPRec, *this);
389
390 // Beginning of range lies in the preamble but it also extends beyond
391 // it into the main file. Split the range into 2 parts, one covering
392 // the preamble and another covering the main file. This allows subsequent
393 // calls to visitPreprocessedEntitiesInRange to accept a source range that
394 // lies in the same FileID, allowing it to skip preprocessed entities that
395 // do not come from the same FileID.
396 bool breaked =
397 visitPreprocessedEntitiesInRange(
398 SourceRange(B, AU->getEndOfPreambleFileID()),
399 PPRec, *this);
400 if (breaked) return true;
401 return visitPreprocessedEntitiesInRange(
402 SourceRange(AU->getStartOfMainFileID(), E),
403 PPRec, *this);
404 }
405
406 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
407 }
408
409 bool OnlyLocalDecls
410 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
411
412 if (OnlyLocalDecls)
413 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
414 PPRec);
415
416 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
417}
418
419template<typename InputIterator>
420bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
421 InputIterator Last,
422 PreprocessingRecord &PPRec,
423 FileID FID) {
424 for (; First != Last; ++First) {
425 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
426 continue;
427
428 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis333e44c2013-05-07 20:37:17 +0000429 if (!PPE)
430 continue;
431
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000432 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
433 if (Visit(MakeMacroExpansionCursor(ME, TU)))
434 return true;
435
436 continue;
437 }
438
439 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
440 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
441 return true;
442
443 continue;
444 }
445
446 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
447 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
448 return true;
449
450 continue;
451 }
452 }
453
454 return false;
455}
456
457/// \brief Visit the children of the given cursor.
458///
459/// \returns true if the visitation should be aborted, false if it
460/// should continue.
461bool CursorVisitor::VisitChildren(CXCursor Cursor) {
462 if (clang_isReference(Cursor.kind) &&
463 Cursor.kind != CXCursor_CXXBaseSpecifier) {
464 // By definition, references have no children.
465 return false;
466 }
467
468 // Set the Parent field to Cursor, then back to its old value once we're
469 // done.
470 SetParentRAII SetParent(Parent, StmtParent, Cursor);
471
472 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +0000473 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000474 if (!D)
475 return false;
476
477 return VisitAttributes(D) || Visit(D);
478 }
479
480 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +0000481 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000482 return Visit(S);
483
484 return false;
485 }
486
487 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +0000488 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000489 return Visit(E);
490
491 return false;
492 }
493
494 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000495 CXTranslationUnit TU = getCursorTU(Cursor);
496 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000497
498 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
499 for (unsigned I = 0; I != 2; ++I) {
500 if (VisitOrder[I]) {
501 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
502 RegionOfInterest.isInvalid()) {
503 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
504 TLEnd = CXXUnit->top_level_end();
505 TL != TLEnd; ++TL) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000506 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000507 return true;
508 }
509 } else if (VisitDeclContext(
510 CXXUnit->getASTContext().getTranslationUnitDecl()))
511 return true;
512 continue;
513 }
514
515 // Walk the preprocessing record.
516 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
517 visitPreprocessedEntitiesInRegion();
518 }
519
520 return false;
521 }
522
523 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +0000524 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000525 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
526 return Visit(BaseTSInfo->getTypeLoc());
527 }
528 }
529 }
530
531 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +0000532 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000533 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
534 if (const ObjCInterfaceType *InterT = A->getInterface()->getAs<ObjCInterfaceType>())
535 return Visit(cxcursor::MakeCursorObjCClassRef(InterT->getInterface(),
536 A->getInterfaceLoc(), TU));
537 }
538
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +0000539 // If pointing inside a macro definition, check if the token is an identifier
540 // that was ever defined as a macro. In such a case, create a "pseudo" macro
541 // expansion cursor for that token.
542 SourceLocation BeginLoc = RegionOfInterest.getBegin();
543 if (Cursor.kind == CXCursor_MacroDefinition &&
544 BeginLoc == RegionOfInterest.getEnd()) {
545 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenko67812b22013-01-11 21:01:49 +0000546 const MacroInfo *MI =
547 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +0000548 if (MacroDefinition *MacroDef =
549 checkForMacroInMacroDefinition(MI, Loc, TU))
550 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
551 }
552
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000553 // Nothing to visit at the moment.
554 return false;
555}
556
557bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
558 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
559 if (Visit(TSInfo->getTypeLoc()))
560 return true;
561
562 if (Stmt *Body = B->getBody())
563 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
564
565 return false;
566}
567
Ted Kremenek943f9092013-02-21 01:29:01 +0000568Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000569 if (RegionOfInterest.isValid()) {
570 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
571 if (Range.isInvalid())
David Blaikie66874fb2013-02-21 01:47:18 +0000572 return None;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000573
574 switch (CompareRegionOfInterest(Range)) {
575 case RangeBefore:
576 // This declaration comes before the region of interest; skip it.
David Blaikie66874fb2013-02-21 01:47:18 +0000577 return None;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000578
579 case RangeAfter:
580 // This declaration comes after the region of interest; we're done.
581 return false;
582
583 case RangeOverlap:
584 // This declaration overlaps the region of interest; visit it.
585 break;
586 }
587 }
588 return true;
589}
590
591bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
592 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
593
594 // FIXME: Eventually remove. This part of a hack to support proper
595 // iteration over all Decls contained lexically within an ObjC container.
596 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
597 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
598
599 for ( ; I != E; ++I) {
600 Decl *D = *I;
601 if (D->getLexicalDeclContext() != DC)
602 continue;
603 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
604
605 // Ignore synthesized ivars here, otherwise if we have something like:
606 // @synthesize prop = _prop;
607 // and '_prop' is not declared, we will encounter a '_prop' ivar before
608 // encountering the 'prop' synthesize declaration and we will think that
609 // we passed the region-of-interest.
610 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
611 if (ivarD->getSynthesize())
612 continue;
613 }
614
615 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
616 // declarations is a mismatch with the compiler semantics.
617 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
618 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
619 if (!ID->isThisDeclarationADefinition())
620 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
621
622 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
623 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
624 if (!PD->isThisDeclarationADefinition())
625 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
626 }
627
Ted Kremenek943f9092013-02-21 01:29:01 +0000628 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000629 if (!V.hasValue())
630 continue;
631 if (!V.getValue())
632 return false;
633 if (Visit(Cursor, true))
634 return true;
635 }
636 return false;
637}
638
639bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
640 llvm_unreachable("Translation units are visited directly by Visit()");
641}
642
643bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
644 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
645 return Visit(TSInfo->getTypeLoc());
646
647 return false;
648}
649
650bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
651 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
652 return Visit(TSInfo->getTypeLoc());
653
654 return false;
655}
656
657bool CursorVisitor::VisitTagDecl(TagDecl *D) {
658 return VisitDeclContext(D);
659}
660
661bool CursorVisitor::VisitClassTemplateSpecializationDecl(
662 ClassTemplateSpecializationDecl *D) {
663 bool ShouldVisitBody = false;
664 switch (D->getSpecializationKind()) {
665 case TSK_Undeclared:
666 case TSK_ImplicitInstantiation:
667 // Nothing to visit
668 return false;
669
670 case TSK_ExplicitInstantiationDeclaration:
671 case TSK_ExplicitInstantiationDefinition:
672 break;
673
674 case TSK_ExplicitSpecialization:
675 ShouldVisitBody = true;
676 break;
677 }
678
679 // Visit the template arguments used in the specialization.
680 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
681 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie39e6ab42013-02-18 22:06:02 +0000682 if (TemplateSpecializationTypeLoc TSTLoc =
683 TL.getAs<TemplateSpecializationTypeLoc>()) {
684 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
685 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000686 return true;
687 }
688 }
689
690 if (ShouldVisitBody && VisitCXXRecordDecl(D))
691 return true;
692
693 return false;
694}
695
696bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
697 ClassTemplatePartialSpecializationDecl *D) {
698 // FIXME: Visit the "outer" template parameter lists on the TagDecl
699 // before visiting these template parameters.
700 if (VisitTemplateParameters(D->getTemplateParameters()))
701 return true;
702
703 // Visit the partial specialization arguments.
704 const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten();
705 for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I)
706 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
707 return true;
708
709 return VisitCXXRecordDecl(D);
710}
711
712bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
713 // Visit the default argument.
714 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
715 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
716 if (Visit(DefArg->getTypeLoc()))
717 return true;
718
719 return false;
720}
721
722bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
723 if (Expr *Init = D->getInitExpr())
724 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
725 return false;
726}
727
728bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis516143b2013-04-05 21:04:10 +0000729 unsigned NumParamList = DD->getNumTemplateParameterLists();
730 for (unsigned i = 0; i < NumParamList; i++) {
731 TemplateParameterList* Params = DD->getTemplateParameterList(i);
732 if (VisitTemplateParameters(Params))
733 return true;
734 }
735
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000736 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
737 if (Visit(TSInfo->getTypeLoc()))
738 return true;
739
740 // Visit the nested-name-specifier, if present.
741 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
742 if (VisitNestedNameSpecifierLoc(QualifierLoc))
743 return true;
744
745 return false;
746}
747
748/// \brief Compare two base or member initializers based on their source order.
749static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
750 CXXCtorInitializer const * const *X
751 = static_cast<CXXCtorInitializer const * const *>(Xp);
752 CXXCtorInitializer const * const *Y
753 = static_cast<CXXCtorInitializer const * const *>(Yp);
754
755 if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
756 return -1;
757 else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
758 return 1;
759 else
760 return 0;
761}
762
763bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis516143b2013-04-05 21:04:10 +0000764 unsigned NumParamList = ND->getNumTemplateParameterLists();
765 for (unsigned i = 0; i < NumParamList; i++) {
766 TemplateParameterList* Params = ND->getTemplateParameterList(i);
767 if (VisitTemplateParameters(Params))
768 return true;
769 }
770
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000771 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
772 // Visit the function declaration's syntactic components in the order
773 // written. This requires a bit of work.
774 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie39e6ab42013-02-18 22:06:02 +0000775 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000776
777 // If we have a function declared directly (without the use of a typedef),
778 // visit just the return type. Otherwise, just visit the function's type
779 // now.
David Blaikie39e6ab42013-02-18 22:06:02 +0000780 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getResultLoc())) ||
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000781 (!FTL && Visit(TL)))
782 return true;
783
784 // Visit the nested-name-specifier, if present.
785 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
786 if (VisitNestedNameSpecifierLoc(QualifierLoc))
787 return true;
788
789 // Visit the declaration name.
790 if (VisitDeclarationNameInfo(ND->getNameInfo()))
791 return true;
792
793 // FIXME: Visit explicitly-specified template arguments!
794
795 // Visit the function parameters, if we have a function type.
David Blaikie39e6ab42013-02-18 22:06:02 +0000796 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000797 return true;
798
Bill Wendlingad017fa2012-12-20 19:22:21 +0000799 // FIXME: Attributes?
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000800 }
801
802 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
803 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
804 // Find the initializers that were written in the source.
805 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
806 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
807 IEnd = Constructor->init_end();
808 I != IEnd; ++I) {
809 if (!(*I)->isWritten())
810 continue;
811
812 WrittenInits.push_back(*I);
813 }
814
815 // Sort the initializers in source order
816 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
817 &CompareCXXCtorInitializers);
818
819 // Visit the initializers in source order
820 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
821 CXXCtorInitializer *Init = WrittenInits[I];
822 if (Init->isAnyMemberInitializer()) {
823 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
824 Init->getMemberLocation(), TU)))
825 return true;
826 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
827 if (Visit(TInfo->getTypeLoc()))
828 return true;
829 }
830
831 // Visit the initializer value.
832 if (Expr *Initializer = Init->getInit())
833 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
834 return true;
835 }
836 }
837
838 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
839 return true;
840 }
841
842 return false;
843}
844
845bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
846 if (VisitDeclaratorDecl(D))
847 return true;
848
849 if (Expr *BitWidth = D->getBitWidth())
850 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
851
852 return false;
853}
854
855bool CursorVisitor::VisitVarDecl(VarDecl *D) {
856 if (VisitDeclaratorDecl(D))
857 return true;
858
859 if (Expr *Init = D->getInit())
860 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
861
862 return false;
863}
864
865bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
866 if (VisitDeclaratorDecl(D))
867 return true;
868
869 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
870 if (Expr *DefArg = D->getDefaultArgument())
871 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
872
873 return false;
874}
875
876bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
877 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
878 // before visiting these template parameters.
879 if (VisitTemplateParameters(D->getTemplateParameters()))
880 return true;
881
882 return VisitFunctionDecl(D->getTemplatedDecl());
883}
884
885bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
886 // FIXME: Visit the "outer" template parameter lists on the TagDecl
887 // before visiting these template parameters.
888 if (VisitTemplateParameters(D->getTemplateParameters()))
889 return true;
890
891 return VisitCXXRecordDecl(D->getTemplatedDecl());
892}
893
894bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
895 if (VisitTemplateParameters(D->getTemplateParameters()))
896 return true;
897
898 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
899 VisitTemplateArgumentLoc(D->getDefaultArgument()))
900 return true;
901
902 return false;
903}
904
905bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
906 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
907 if (Visit(TSInfo->getTypeLoc()))
908 return true;
909
910 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
911 PEnd = ND->param_end();
912 P != PEnd; ++P) {
913 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
914 return true;
915 }
916
917 if (ND->isThisDeclarationADefinition() &&
918 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
919 return true;
920
921 return false;
922}
923
924template <typename DeclIt>
925static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
926 SourceManager &SM, SourceLocation EndLoc,
927 SmallVectorImpl<Decl *> &Decls) {
928 DeclIt next = *DI_current;
929 while (++next != DE_current) {
930 Decl *D_next = *next;
931 if (!D_next)
932 break;
933 SourceLocation L = D_next->getLocStart();
934 if (!L.isValid())
935 break;
936 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
937 *DI_current = next;
938 Decls.push_back(D_next);
939 continue;
940 }
941 break;
942 }
943}
944
945namespace {
946 struct ContainerDeclsSort {
947 SourceManager &SM;
948 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
949 bool operator()(Decl *A, Decl *B) {
950 SourceLocation L_A = A->getLocStart();
951 SourceLocation L_B = B->getLocStart();
952 assert(L_A.isValid() && L_B.isValid());
953 return SM.isBeforeInTranslationUnit(L_A, L_B);
954 }
955 };
956}
957
958bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
959 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
960 // an @implementation can lexically contain Decls that are not properly
961 // nested in the AST. When we identify such cases, we need to retrofit
962 // this nesting here.
963 if (!DI_current && !FileDI_current)
964 return VisitDeclContext(D);
965
966 // Scan the Decls that immediately come after the container
967 // in the current DeclContext. If any fall within the
968 // container's lexical region, stash them into a vector
969 // for later processing.
970 SmallVector<Decl *, 24> DeclsInContainer;
971 SourceLocation EndLoc = D->getSourceRange().getEnd();
972 SourceManager &SM = AU->getSourceManager();
973 if (EndLoc.isValid()) {
974 if (DI_current) {
975 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
976 DeclsInContainer);
977 } else {
978 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
979 DeclsInContainer);
980 }
981 }
982
983 // The common case.
984 if (DeclsInContainer.empty())
985 return VisitDeclContext(D);
986
987 // Get all the Decls in the DeclContext, and sort them with the
988 // additional ones we've collected. Then visit them.
989 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
990 I!=E; ++I) {
991 Decl *subDecl = *I;
992 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
993 subDecl->getLocStart().isInvalid())
994 continue;
995 DeclsInContainer.push_back(subDecl);
996 }
997
998 // Now sort the Decls so that they appear in lexical order.
999 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
1000 ContainerDeclsSort(SM));
1001
1002 // Now visit the decls.
1003 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1004 E = DeclsInContainer.end(); I != E; ++I) {
1005 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek943f9092013-02-21 01:29:01 +00001006 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001007 if (!V.hasValue())
1008 continue;
1009 if (!V.getValue())
1010 return false;
1011 if (Visit(Cursor, true))
1012 return true;
1013 }
1014 return false;
1015}
1016
1017bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1018 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1019 TU)))
1020 return true;
1021
1022 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1023 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1024 E = ND->protocol_end(); I != E; ++I, ++PL)
1025 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1026 return true;
1027
1028 return VisitObjCContainerDecl(ND);
1029}
1030
1031bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1032 if (!PID->isThisDeclarationADefinition())
1033 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1034
1035 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1036 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1037 E = PID->protocol_end(); I != E; ++I, ++PL)
1038 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1039 return true;
1040
1041 return VisitObjCContainerDecl(PID);
1042}
1043
1044bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1045 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1046 return true;
1047
1048 // FIXME: This implements a workaround with @property declarations also being
1049 // installed in the DeclContext for the @interface. Eventually this code
1050 // should be removed.
1051 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1052 if (!CDecl || !CDecl->IsClassExtension())
1053 return false;
1054
1055 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1056 if (!ID)
1057 return false;
1058
1059 IdentifierInfo *PropertyId = PD->getIdentifier();
1060 ObjCPropertyDecl *prevDecl =
1061 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1062
1063 if (!prevDecl)
1064 return false;
1065
1066 // Visit synthesized methods since they will be skipped when visiting
1067 // the @interface.
1068 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1069 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1070 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1071 return true;
1072
1073 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1074 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1075 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1076 return true;
1077
1078 return false;
1079}
1080
1081bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1082 if (!D->isThisDeclarationADefinition()) {
1083 // Forward declaration is treated like a reference.
1084 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1085 }
1086
1087 // Issue callbacks for super class.
1088 if (D->getSuperClass() &&
1089 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1090 D->getSuperClassLoc(),
1091 TU)))
1092 return true;
1093
1094 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1095 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1096 E = D->protocol_end(); I != E; ++I, ++PL)
1097 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1098 return true;
1099
1100 return VisitObjCContainerDecl(D);
1101}
1102
1103bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1104 return VisitObjCContainerDecl(D);
1105}
1106
1107bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1108 // 'ID' could be null when dealing with invalid code.
1109 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1110 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1111 return true;
1112
1113 return VisitObjCImplDecl(D);
1114}
1115
1116bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1117#if 0
1118 // Issue callbacks for super class.
1119 // FIXME: No source location information!
1120 if (D->getSuperClass() &&
1121 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1122 D->getSuperClassLoc(),
1123 TU)))
1124 return true;
1125#endif
1126
1127 return VisitObjCImplDecl(D);
1128}
1129
1130bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1131 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1132 if (PD->isIvarNameSpecified())
1133 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1134
1135 return false;
1136}
1137
1138bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1139 return VisitDeclContext(D);
1140}
1141
1142bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1143 // Visit nested-name-specifier.
1144 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1145 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1146 return true;
1147
1148 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1149 D->getTargetNameLoc(), TU));
1150}
1151
1152bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1153 // Visit nested-name-specifier.
1154 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1155 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1156 return true;
1157 }
1158
1159 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1160 return true;
1161
1162 return VisitDeclarationNameInfo(D->getNameInfo());
1163}
1164
1165bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1166 // Visit nested-name-specifier.
1167 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1168 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1169 return true;
1170
1171 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1172 D->getIdentLocation(), TU));
1173}
1174
1175bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1176 // Visit nested-name-specifier.
1177 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1178 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1179 return true;
1180 }
1181
1182 return VisitDeclarationNameInfo(D->getNameInfo());
1183}
1184
1185bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1186 UnresolvedUsingTypenameDecl *D) {
1187 // Visit nested-name-specifier.
1188 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1189 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1190 return true;
1191
1192 return false;
1193}
1194
1195bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1196 switch (Name.getName().getNameKind()) {
1197 case clang::DeclarationName::Identifier:
1198 case clang::DeclarationName::CXXLiteralOperatorName:
1199 case clang::DeclarationName::CXXOperatorName:
1200 case clang::DeclarationName::CXXUsingDirective:
1201 return false;
1202
1203 case clang::DeclarationName::CXXConstructorName:
1204 case clang::DeclarationName::CXXDestructorName:
1205 case clang::DeclarationName::CXXConversionFunctionName:
1206 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1207 return Visit(TSInfo->getTypeLoc());
1208 return false;
1209
1210 case clang::DeclarationName::ObjCZeroArgSelector:
1211 case clang::DeclarationName::ObjCOneArgSelector:
1212 case clang::DeclarationName::ObjCMultiArgSelector:
1213 // FIXME: Per-identifier location info?
1214 return false;
1215 }
1216
1217 llvm_unreachable("Invalid DeclarationName::Kind!");
1218}
1219
1220bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1221 SourceRange Range) {
1222 // FIXME: This whole routine is a hack to work around the lack of proper
1223 // source information in nested-name-specifiers (PR5791). Since we do have
1224 // a beginning source location, we can visit the first component of the
1225 // nested-name-specifier, if it's a single-token component.
1226 if (!NNS)
1227 return false;
1228
1229 // Get the first component in the nested-name-specifier.
1230 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1231 NNS = Prefix;
1232
1233 switch (NNS->getKind()) {
1234 case NestedNameSpecifier::Namespace:
1235 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1236 TU));
1237
1238 case NestedNameSpecifier::NamespaceAlias:
1239 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1240 Range.getBegin(), TU));
1241
1242 case NestedNameSpecifier::TypeSpec: {
1243 // If the type has a form where we know that the beginning of the source
1244 // range matches up with a reference cursor. Visit the appropriate reference
1245 // cursor.
1246 const Type *T = NNS->getAsType();
1247 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1248 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1249 if (const TagType *Tag = dyn_cast<TagType>(T))
1250 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1251 if (const TemplateSpecializationType *TST
1252 = dyn_cast<TemplateSpecializationType>(T))
1253 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1254 break;
1255 }
1256
1257 case NestedNameSpecifier::TypeSpecWithTemplate:
1258 case NestedNameSpecifier::Global:
1259 case NestedNameSpecifier::Identifier:
1260 break;
1261 }
1262
1263 return false;
1264}
1265
1266bool
1267CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1268 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1269 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1270 Qualifiers.push_back(Qualifier);
1271
1272 while (!Qualifiers.empty()) {
1273 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1274 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1275 switch (NNS->getKind()) {
1276 case NestedNameSpecifier::Namespace:
1277 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1278 Q.getLocalBeginLoc(),
1279 TU)))
1280 return true;
1281
1282 break;
1283
1284 case NestedNameSpecifier::NamespaceAlias:
1285 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1286 Q.getLocalBeginLoc(),
1287 TU)))
1288 return true;
1289
1290 break;
1291
1292 case NestedNameSpecifier::TypeSpec:
1293 case NestedNameSpecifier::TypeSpecWithTemplate:
1294 if (Visit(Q.getTypeLoc()))
1295 return true;
1296
1297 break;
1298
1299 case NestedNameSpecifier::Global:
1300 case NestedNameSpecifier::Identifier:
1301 break;
1302 }
1303 }
1304
1305 return false;
1306}
1307
1308bool CursorVisitor::VisitTemplateParameters(
1309 const TemplateParameterList *Params) {
1310 if (!Params)
1311 return false;
1312
1313 for (TemplateParameterList::const_iterator P = Params->begin(),
1314 PEnd = Params->end();
1315 P != PEnd; ++P) {
1316 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1317 return true;
1318 }
1319
1320 return false;
1321}
1322
1323bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1324 switch (Name.getKind()) {
1325 case TemplateName::Template:
1326 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1327
1328 case TemplateName::OverloadedTemplate:
1329 // Visit the overloaded template set.
1330 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1331 return true;
1332
1333 return false;
1334
1335 case TemplateName::DependentTemplate:
1336 // FIXME: Visit nested-name-specifier.
1337 return false;
1338
1339 case TemplateName::QualifiedTemplate:
1340 // FIXME: Visit nested-name-specifier.
1341 return Visit(MakeCursorTemplateRef(
1342 Name.getAsQualifiedTemplateName()->getDecl(),
1343 Loc, TU));
1344
1345 case TemplateName::SubstTemplateTemplateParm:
1346 return Visit(MakeCursorTemplateRef(
1347 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1348 Loc, TU));
1349
1350 case TemplateName::SubstTemplateTemplateParmPack:
1351 return Visit(MakeCursorTemplateRef(
1352 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1353 Loc, TU));
1354 }
1355
1356 llvm_unreachable("Invalid TemplateName::Kind!");
1357}
1358
1359bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1360 switch (TAL.getArgument().getKind()) {
1361 case TemplateArgument::Null:
1362 case TemplateArgument::Integral:
1363 case TemplateArgument::Pack:
1364 return false;
1365
1366 case TemplateArgument::Type:
1367 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1368 return Visit(TSInfo->getTypeLoc());
1369 return false;
1370
1371 case TemplateArgument::Declaration:
1372 if (Expr *E = TAL.getSourceDeclExpression())
1373 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1374 return false;
1375
1376 case TemplateArgument::NullPtr:
1377 if (Expr *E = TAL.getSourceNullPtrExpression())
1378 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1379 return false;
1380
1381 case TemplateArgument::Expression:
1382 if (Expr *E = TAL.getSourceExpression())
1383 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1384 return false;
1385
1386 case TemplateArgument::Template:
1387 case TemplateArgument::TemplateExpansion:
1388 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1389 return true;
1390
1391 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1392 TAL.getTemplateNameLoc());
1393 }
1394
1395 llvm_unreachable("Invalid TemplateArgument::Kind!");
1396}
1397
1398bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1399 return VisitDeclContext(D);
1400}
1401
1402bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1403 return Visit(TL.getUnqualifiedLoc());
1404}
1405
1406bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1407 ASTContext &Context = AU->getASTContext();
1408
1409 // Some builtin types (such as Objective-C's "id", "sel", and
1410 // "Class") have associated declarations. Create cursors for those.
1411 QualType VisitType;
1412 switch (TL.getTypePtr()->getKind()) {
1413
1414 case BuiltinType::Void:
1415 case BuiltinType::NullPtr:
1416 case BuiltinType::Dependent:
Guy Benyeib13621d2012-12-18 14:38:23 +00001417 case BuiltinType::OCLImage1d:
1418 case BuiltinType::OCLImage1dArray:
1419 case BuiltinType::OCLImage1dBuffer:
1420 case BuiltinType::OCLImage2d:
1421 case BuiltinType::OCLImage2dArray:
1422 case BuiltinType::OCLImage3d:
NAKAMURA Takumi775bb8a2013-02-07 12:47:42 +00001423 case BuiltinType::OCLSampler:
Guy Benyeie6b9d802013-01-20 12:31:11 +00001424 case BuiltinType::OCLEvent:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001425#define BUILTIN_TYPE(Id, SingletonId)
1426#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1427#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1428#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1429#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1430#include "clang/AST/BuiltinTypes.def"
1431 break;
1432
1433 case BuiltinType::ObjCId:
1434 VisitType = Context.getObjCIdType();
1435 break;
1436
1437 case BuiltinType::ObjCClass:
1438 VisitType = Context.getObjCClassType();
1439 break;
1440
1441 case BuiltinType::ObjCSel:
1442 VisitType = Context.getObjCSelType();
1443 break;
1444 }
1445
1446 if (!VisitType.isNull()) {
1447 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1448 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1449 TU));
1450 }
1451
1452 return false;
1453}
1454
1455bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1456 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1457}
1458
1459bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1460 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1461}
1462
1463bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1464 if (TL.isDefinition())
1465 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1466
1467 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1468}
1469
1470bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1471 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1472}
1473
1474bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1475 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1476 return true;
1477
1478 return false;
1479}
1480
1481bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1482 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1483 return true;
1484
1485 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1486 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1487 TU)))
1488 return true;
1489 }
1490
1491 return false;
1492}
1493
1494bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1495 return Visit(TL.getPointeeLoc());
1496}
1497
1498bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1499 return Visit(TL.getInnerLoc());
1500}
1501
1502bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1503 return Visit(TL.getPointeeLoc());
1504}
1505
1506bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1507 return Visit(TL.getPointeeLoc());
1508}
1509
1510bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1511 return Visit(TL.getPointeeLoc());
1512}
1513
1514bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1515 return Visit(TL.getPointeeLoc());
1516}
1517
1518bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1519 return Visit(TL.getPointeeLoc());
1520}
1521
1522bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1523 return Visit(TL.getModifiedLoc());
1524}
1525
1526bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1527 bool SkipResultType) {
1528 if (!SkipResultType && Visit(TL.getResultLoc()))
1529 return true;
1530
1531 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1532 if (Decl *D = TL.getArg(I))
1533 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1534 return true;
1535
1536 return false;
1537}
1538
1539bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1540 if (Visit(TL.getElementLoc()))
1541 return true;
1542
1543 if (Expr *Size = TL.getSizeExpr())
1544 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1545
1546 return false;
1547}
1548
1549bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1550 TemplateSpecializationTypeLoc TL) {
1551 // Visit the template name.
1552 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1553 TL.getTemplateNameLoc()))
1554 return true;
1555
1556 // Visit the template arguments.
1557 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1558 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1559 return true;
1560
1561 return false;
1562}
1563
1564bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1565 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1566}
1567
1568bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1569 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1570 return Visit(TSInfo->getTypeLoc());
1571
1572 return false;
1573}
1574
1575bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1576 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1577 return Visit(TSInfo->getTypeLoc());
1578
1579 return false;
1580}
1581
1582bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1583 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1584 return true;
1585
1586 return false;
1587}
1588
1589bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1590 DependentTemplateSpecializationTypeLoc TL) {
1591 // Visit the nested-name-specifier, if there is one.
1592 if (TL.getQualifierLoc() &&
1593 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1594 return true;
1595
1596 // Visit the template arguments.
1597 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1598 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1599 return true;
1600
1601 return false;
1602}
1603
1604bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1605 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1606 return true;
1607
1608 return Visit(TL.getNamedTypeLoc());
1609}
1610
1611bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1612 return Visit(TL.getPatternLoc());
1613}
1614
1615bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1616 if (Expr *E = TL.getUnderlyingExpr())
1617 return Visit(MakeCXCursor(E, StmtParent, TU));
1618
1619 return false;
1620}
1621
1622bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1623 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1624}
1625
1626bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1627 return Visit(TL.getValueLoc());
1628}
1629
1630#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1631bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1632 return Visit##PARENT##Loc(TL); \
1633}
1634
1635DEFAULT_TYPELOC_IMPL(Complex, Type)
1636DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1637DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1638DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1639DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1640DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1641DEFAULT_TYPELOC_IMPL(Vector, Type)
1642DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1643DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1644DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1645DEFAULT_TYPELOC_IMPL(Record, TagType)
1646DEFAULT_TYPELOC_IMPL(Enum, TagType)
1647DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1648DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1649DEFAULT_TYPELOC_IMPL(Auto, Type)
1650
1651bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1652 // Visit the nested-name-specifier, if present.
1653 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1654 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1655 return true;
1656
1657 if (D->isCompleteDefinition()) {
1658 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1659 E = D->bases_end(); I != E; ++I) {
1660 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1661 return true;
1662 }
1663 }
1664
1665 return VisitTagDecl(D);
1666}
1667
1668bool CursorVisitor::VisitAttributes(Decl *D) {
1669 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1670 i != e; ++i)
1671 if (Visit(MakeCXCursor(*i, D, TU)))
1672 return true;
1673
1674 return false;
1675}
1676
1677//===----------------------------------------------------------------------===//
1678// Data-recursive visitor methods.
1679//===----------------------------------------------------------------------===//
1680
1681namespace {
1682#define DEF_JOB(NAME, DATA, KIND)\
1683class NAME : public VisitorJob {\
1684public:\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001685 NAME(const DATA *d, CXCursor parent) : \
1686 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001687 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001688 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001689};
1690
1691DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1692DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1693DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1694DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1695DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1696 ExplicitTemplateArgsVisitKind)
1697DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1698DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1699DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1700#undef DEF_JOB
1701
1702class DeclVisit : public VisitorJob {
1703public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001704 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001705 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001706 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001707 static bool classof(const VisitorJob *VJ) {
1708 return VJ->getKind() == DeclVisitKind;
1709 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001710 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001711 bool isFirst() const { return data[1] ? true : false; }
1712};
1713class TypeLocVisit : public VisitorJob {
1714public:
1715 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1716 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1717 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1718
1719 static bool classof(const VisitorJob *VJ) {
1720 return VJ->getKind() == TypeLocVisitKind;
1721 }
1722
1723 TypeLoc get() const {
1724 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001725 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001726 }
1727};
1728
1729class LabelRefVisit : public VisitorJob {
1730public:
1731 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1732 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1733 labelLoc.getPtrEncoding()) {}
1734
1735 static bool classof(const VisitorJob *VJ) {
1736 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1737 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001738 const LabelDecl *get() const {
1739 return static_cast<const LabelDecl *>(data[0]);
1740 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001741 SourceLocation getLoc() const {
1742 return SourceLocation::getFromPtrEncoding(data[1]); }
1743};
1744
1745class NestedNameSpecifierLocVisit : public VisitorJob {
1746public:
1747 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1748 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1749 Qualifier.getNestedNameSpecifier(),
1750 Qualifier.getOpaqueData()) { }
1751
1752 static bool classof(const VisitorJob *VJ) {
1753 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1754 }
1755
1756 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001757 return NestedNameSpecifierLoc(
1758 const_cast<NestedNameSpecifier *>(
1759 static_cast<const NestedNameSpecifier *>(data[0])),
1760 const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001761 }
1762};
1763
1764class DeclarationNameInfoVisit : public VisitorJob {
1765public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001766 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001767 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001768 static bool classof(const VisitorJob *VJ) {
1769 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1770 }
1771 DeclarationNameInfo get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001772 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001773 switch (S->getStmtClass()) {
1774 default:
1775 llvm_unreachable("Unhandled Stmt");
1776 case clang::Stmt::MSDependentExistsStmtClass:
1777 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1778 case Stmt::CXXDependentScopeMemberExprClass:
1779 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1780 case Stmt::DependentScopeDeclRefExprClass:
1781 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1782 }
1783 }
1784};
1785class MemberRefVisit : public VisitorJob {
1786public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001787 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001788 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1789 L.getPtrEncoding()) {}
1790 static bool classof(const VisitorJob *VJ) {
1791 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1792 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001793 const FieldDecl *get() const {
1794 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001795 }
1796 SourceLocation getLoc() const {
1797 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1798 }
1799};
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001800class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001801 VisitorWorkList &WL;
1802 CXCursor Parent;
1803public:
1804 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1805 : WL(wl), Parent(parent) {}
1806
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001807 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1808 void VisitBlockExpr(const BlockExpr *B);
1809 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1810 void VisitCompoundStmt(const CompoundStmt *S);
1811 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1812 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1813 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1814 void VisitCXXNewExpr(const CXXNewExpr *E);
1815 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1816 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1817 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1818 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1819 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1820 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1821 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1822 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1823 void VisitDeclRefExpr(const DeclRefExpr *D);
1824 void VisitDeclStmt(const DeclStmt *S);
1825 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1826 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1827 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1828 void VisitForStmt(const ForStmt *FS);
1829 void VisitGotoStmt(const GotoStmt *GS);
1830 void VisitIfStmt(const IfStmt *If);
1831 void VisitInitListExpr(const InitListExpr *IE);
1832 void VisitMemberExpr(const MemberExpr *M);
1833 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1834 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1835 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1836 void VisitOverloadExpr(const OverloadExpr *E);
1837 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1838 void VisitStmt(const Stmt *S);
1839 void VisitSwitchStmt(const SwitchStmt *S);
1840 void VisitWhileStmt(const WhileStmt *W);
1841 void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E);
1842 void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E);
1843 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1844 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1845 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1846 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1847 void VisitVAArgExpr(const VAArgExpr *E);
1848 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1849 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1850 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1851 void VisitLambdaExpr(const LambdaExpr *E);
1852
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001853private:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001854 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001855 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1856 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001857 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1858 void AddStmt(const Stmt *S);
1859 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001860 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001861 void EnqueueChildren(const Stmt *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001862};
1863} // end anonyous namespace
1864
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001865void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001866 // 'S' should always be non-null, since it comes from the
1867 // statement we are visiting.
1868 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1869}
1870
1871void
1872EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1873 if (Qualifier)
1874 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1875}
1876
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001877void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001878 if (S)
1879 WL.push_back(StmtVisit(S, Parent));
1880}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001881void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001882 if (D)
1883 WL.push_back(DeclVisit(D, Parent, isFirst));
1884}
1885void EnqueueVisitor::
1886 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1887 if (A)
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001888 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001889}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001890void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001891 if (D)
1892 WL.push_back(MemberRefVisit(D, L, Parent));
1893}
1894void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1895 if (TI)
1896 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1897 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001898void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001899 unsigned size = WL.size();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001900 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001901 AddStmt(*Child);
1902 }
1903 if (size == WL.size())
1904 return;
1905 // Now reverse the entries we just added. This will match the DFS
1906 // ordering performed by the worklist.
1907 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1908 std::reverse(I, E);
1909}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001910void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001911 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1912}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001913void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001914 AddDecl(B->getBlockDecl());
1915}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001916void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001917 EnqueueChildren(E);
1918 AddTypeLoc(E->getTypeSourceInfo());
1919}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001920void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1921 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001922 E = S->body_rend(); I != E; ++I) {
1923 AddStmt(*I);
1924 }
1925}
1926void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001927VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001928 AddStmt(S->getSubStmt());
1929 AddDeclarationNameInfo(S);
1930 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1931 AddNestedNameSpecifierLoc(QualifierLoc);
1932}
1933
1934void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001935VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001936 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1937 AddDeclarationNameInfo(E);
1938 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1939 AddNestedNameSpecifierLoc(QualifierLoc);
1940 if (!E->isImplicitAccess())
1941 AddStmt(E->getBase());
1942}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001943void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001944 // Enqueue the initializer , if any.
1945 AddStmt(E->getInitializer());
1946 // Enqueue the array size, if any.
1947 AddStmt(E->getArraySize());
1948 // Enqueue the allocated type.
1949 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1950 // Enqueue the placement arguments.
1951 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1952 AddStmt(E->getPlacementArg(I-1));
1953}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001954void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001955 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1956 AddStmt(CE->getArg(I-1));
1957 AddStmt(CE->getCallee());
1958 AddStmt(CE->getArg(0));
1959}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001960void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
1961 const CXXPseudoDestructorExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001962 // Visit the name of the type being destroyed.
1963 AddTypeLoc(E->getDestroyedTypeInfo());
1964 // Visit the scope type that looks disturbingly like the nested-name-specifier
1965 // but isn't.
1966 AddTypeLoc(E->getScopeTypeInfo());
1967 // Visit the nested-name-specifier.
1968 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1969 AddNestedNameSpecifierLoc(QualifierLoc);
1970 // Visit base expression.
1971 AddStmt(E->getBase());
1972}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001973void EnqueueVisitor::VisitCXXScalarValueInitExpr(
1974 const CXXScalarValueInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001975 AddTypeLoc(E->getTypeSourceInfo());
1976}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001977void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
1978 const CXXTemporaryObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001979 EnqueueChildren(E);
1980 AddTypeLoc(E->getTypeSourceInfo());
1981}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001982void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001983 EnqueueChildren(E);
1984 if (E->isTypeOperand())
1985 AddTypeLoc(E->getTypeOperandSourceInfo());
1986}
1987
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001988void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
1989 const CXXUnresolvedConstructExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001990 EnqueueChildren(E);
1991 AddTypeLoc(E->getTypeSourceInfo());
1992}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001993void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001994 EnqueueChildren(E);
1995 if (E->isTypeOperand())
1996 AddTypeLoc(E->getTypeOperandSourceInfo());
1997}
1998
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001999void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002000 EnqueueChildren(S);
2001 AddDecl(S->getExceptionDecl());
2002}
2003
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002004void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002005 if (DR->hasExplicitTemplateArgs()) {
2006 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2007 }
2008 WL.push_back(DeclRefExprParts(DR, Parent));
2009}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002010void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2011 const DependentScopeDeclRefExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002012 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2013 AddDeclarationNameInfo(E);
2014 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2015}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002016void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002017 unsigned size = WL.size();
2018 bool isFirst = true;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002019 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002020 D != DEnd; ++D) {
2021 AddDecl(*D, isFirst);
2022 isFirst = false;
2023 }
2024 if (size == WL.size())
2025 return;
2026 // Now reverse the entries we just added. This will match the DFS
2027 // ordering performed by the worklist.
2028 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2029 std::reverse(I, E);
2030}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002031void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002032 AddStmt(E->getInit());
2033 typedef DesignatedInitExpr::Designator Designator;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002034 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002035 D = E->designators_rbegin(), DEnd = E->designators_rend();
2036 D != DEnd; ++D) {
2037 if (D->isFieldDesignator()) {
2038 if (FieldDecl *Field = D->getField())
2039 AddMemberRef(Field, D->getFieldLoc());
2040 continue;
2041 }
2042 if (D->isArrayDesignator()) {
2043 AddStmt(E->getArrayIndex(*D));
2044 continue;
2045 }
2046 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2047 AddStmt(E->getArrayRangeEnd(*D));
2048 AddStmt(E->getArrayRangeStart(*D));
2049 }
2050}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002051void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002052 EnqueueChildren(E);
2053 AddTypeLoc(E->getTypeInfoAsWritten());
2054}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002055void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002056 AddStmt(FS->getBody());
2057 AddStmt(FS->getInc());
2058 AddStmt(FS->getCond());
2059 AddDecl(FS->getConditionVariable());
2060 AddStmt(FS->getInit());
2061}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002062void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002063 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2064}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002065void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002066 AddStmt(If->getElse());
2067 AddStmt(If->getThen());
2068 AddStmt(If->getCond());
2069 AddDecl(If->getConditionVariable());
2070}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002071void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002072 // We care about the syntactic form of the initializer list, only.
2073 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2074 IE = Syntactic;
2075 EnqueueChildren(IE);
2076}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002077void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002078 WL.push_back(MemberExprParts(M, Parent));
2079
2080 // If the base of the member access expression is an implicit 'this', don't
2081 // visit it.
2082 // FIXME: If we ever want to show these implicit accesses, this will be
2083 // unfortunate. However, clang_getCursor() relies on this behavior.
2084 if (!M->isImplicitAccess())
2085 AddStmt(M->getBase());
2086}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002087void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002088 AddTypeLoc(E->getEncodedTypeSourceInfo());
2089}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002090void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002091 EnqueueChildren(M);
2092 AddTypeLoc(M->getClassReceiverTypeInfo());
2093}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002094void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002095 // Visit the components of the offsetof expression.
2096 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2097 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2098 const OffsetOfNode &Node = E->getComponent(I-1);
2099 switch (Node.getKind()) {
2100 case OffsetOfNode::Array:
2101 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2102 break;
2103 case OffsetOfNode::Field:
2104 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2105 break;
2106 case OffsetOfNode::Identifier:
2107 case OffsetOfNode::Base:
2108 continue;
2109 }
2110 }
2111 // Visit the type into which we're computing the offset.
2112 AddTypeLoc(E->getTypeSourceInfo());
2113}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002114void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002115 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2116 WL.push_back(OverloadExprParts(E, Parent));
2117}
2118void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002119 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002120 EnqueueChildren(E);
2121 if (E->isArgumentType())
2122 AddTypeLoc(E->getArgumentTypeInfo());
2123}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002124void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002125 EnqueueChildren(S);
2126}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002127void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002128 AddStmt(S->getBody());
2129 AddStmt(S->getCond());
2130 AddDecl(S->getConditionVariable());
2131}
2132
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002133void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002134 AddStmt(W->getBody());
2135 AddStmt(W->getCond());
2136 AddDecl(W->getConditionVariable());
2137}
2138
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002139void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002140 AddTypeLoc(E->getQueriedTypeSourceInfo());
2141}
2142
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002143void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002144 AddTypeLoc(E->getRhsTypeSourceInfo());
2145 AddTypeLoc(E->getLhsTypeSourceInfo());
2146}
2147
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002148void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002149 for (unsigned I = E->getNumArgs(); I > 0; --I)
2150 AddTypeLoc(E->getArg(I-1));
2151}
2152
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002153void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002154 AddTypeLoc(E->getQueriedTypeSourceInfo());
2155}
2156
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002157void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002158 EnqueueChildren(E);
2159}
2160
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002161void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002162 VisitOverloadExpr(U);
2163 if (!U->isImplicitAccess())
2164 AddStmt(U->getBase());
2165}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002166void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002167 AddStmt(E->getSubExpr());
2168 AddTypeLoc(E->getWrittenTypeInfo());
2169}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002170void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002171 WL.push_back(SizeOfPackExprParts(E, Parent));
2172}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002173void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002174 // If the opaque value has a source expression, just transparently
2175 // visit that. This is useful for (e.g.) pseudo-object expressions.
2176 if (Expr *SourceExpr = E->getSourceExpr())
2177 return Visit(SourceExpr);
2178}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002179void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002180 AddStmt(E->getBody());
2181 WL.push_back(LambdaExprParts(E, Parent));
2182}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002183void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002184 // Treat the expression like its syntactic form.
2185 Visit(E->getSyntacticForm());
2186}
2187
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002188void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002189 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2190}
2191
2192bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2193 if (RegionOfInterest.isValid()) {
2194 SourceRange Range = getRawCursorExtent(C);
2195 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2196 return false;
2197 }
2198 return true;
2199}
2200
2201bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2202 while (!WL.empty()) {
2203 // Dequeue the worklist item.
2204 VisitorJob LI = WL.back();
2205 WL.pop_back();
2206
2207 // Set the Parent field, then back to its old value once we're done.
2208 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2209
2210 switch (LI.getKind()) {
2211 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002212 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002213 if (!D)
2214 continue;
2215
2216 // For now, perform default visitation for Decls.
2217 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2218 cast<DeclVisit>(&LI)->isFirst())))
2219 return true;
2220
2221 continue;
2222 }
2223 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2224 const ASTTemplateArgumentListInfo *ArgList =
2225 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2226 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2227 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2228 Arg != ArgEnd; ++Arg) {
2229 if (VisitTemplateArgumentLoc(*Arg))
2230 return true;
2231 }
2232 continue;
2233 }
2234 case VisitorJob::TypeLocVisitKind: {
2235 // Perform default visitation for TypeLocs.
2236 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2237 return true;
2238 continue;
2239 }
2240 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002241 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002242 if (LabelStmt *stmt = LS->getStmt()) {
2243 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2244 TU))) {
2245 return true;
2246 }
2247 }
2248 continue;
2249 }
2250
2251 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2252 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2253 if (VisitNestedNameSpecifierLoc(V->get()))
2254 return true;
2255 continue;
2256 }
2257
2258 case VisitorJob::DeclarationNameInfoVisitKind: {
2259 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2260 ->get()))
2261 return true;
2262 continue;
2263 }
2264 case VisitorJob::MemberRefVisitKind: {
2265 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2266 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2267 return true;
2268 continue;
2269 }
2270 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002271 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002272 if (!S)
2273 continue;
2274
2275 // Update the current cursor.
2276 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2277 if (!IsInRegionOfInterest(Cursor))
2278 continue;
2279 switch (Visitor(Cursor, Parent, ClientData)) {
2280 case CXChildVisit_Break: return true;
2281 case CXChildVisit_Continue: break;
2282 case CXChildVisit_Recurse:
2283 if (PostChildrenVisitor)
2284 WL.push_back(PostChildrenVisit(0, Cursor));
2285 EnqueueWorkList(WL, S);
2286 break;
2287 }
2288 continue;
2289 }
2290 case VisitorJob::MemberExprPartsKind: {
2291 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002292 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002293
2294 // Visit the nested-name-specifier
2295 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2296 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2297 return true;
2298
2299 // Visit the declaration name.
2300 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2301 return true;
2302
2303 // Visit the explicitly-specified template arguments, if any.
2304 if (M->hasExplicitTemplateArgs()) {
2305 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2306 *ArgEnd = Arg + M->getNumTemplateArgs();
2307 Arg != ArgEnd; ++Arg) {
2308 if (VisitTemplateArgumentLoc(*Arg))
2309 return true;
2310 }
2311 }
2312 continue;
2313 }
2314 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002315 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002316 // Visit nested-name-specifier, if present.
2317 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2318 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2319 return true;
2320 // Visit declaration name.
2321 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2322 return true;
2323 continue;
2324 }
2325 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002326 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002327 // Visit the nested-name-specifier.
2328 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2329 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2330 return true;
2331 // Visit the declaration name.
2332 if (VisitDeclarationNameInfo(O->getNameInfo()))
2333 return true;
2334 // Visit the overloaded declaration reference.
2335 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2336 return true;
2337 continue;
2338 }
2339 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002340 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002341 NamedDecl *Pack = E->getPack();
2342 if (isa<TemplateTypeParmDecl>(Pack)) {
2343 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2344 E->getPackLoc(), TU)))
2345 return true;
2346
2347 continue;
2348 }
2349
2350 if (isa<TemplateTemplateParmDecl>(Pack)) {
2351 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2352 E->getPackLoc(), TU)))
2353 return true;
2354
2355 continue;
2356 }
2357
2358 // Non-type template parameter packs and function parameter packs are
2359 // treated like DeclRefExpr cursors.
2360 continue;
2361 }
2362
2363 case VisitorJob::LambdaExprPartsKind: {
2364 // Visit captures.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002365 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002366 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2367 CEnd = E->explicit_capture_end();
2368 C != CEnd; ++C) {
Richard Smith0d8e9642013-05-16 06:20:58 +00002369 // FIXME: Lambda init-captures.
2370 if (!C->capturesVariable())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002371 continue;
Richard Smith0d8e9642013-05-16 06:20:58 +00002372
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002373 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2374 C->getLocation(),
2375 TU)))
2376 return true;
2377 }
2378
2379 // Visit parameters and return type, if present.
2380 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2381 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2382 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2383 // Visit the whole type.
2384 if (Visit(TL))
2385 return true;
David Blaikie39e6ab42013-02-18 22:06:02 +00002386 } else if (FunctionProtoTypeLoc Proto =
2387 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002388 if (E->hasExplicitParameters()) {
2389 // Visit parameters.
2390 for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
2391 if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
2392 return true;
2393 } else {
2394 // Visit result type.
2395 if (Visit(Proto.getResultLoc()))
2396 return true;
2397 }
2398 }
2399 }
2400 break;
2401 }
2402
2403 case VisitorJob::PostChildrenVisitKind:
2404 if (PostChildrenVisitor(Parent, ClientData))
2405 return true;
2406 break;
2407 }
2408 }
2409 return false;
2410}
2411
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002412bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002413 VisitorWorkList *WL = 0;
2414 if (!WorkListFreeList.empty()) {
2415 WL = WorkListFreeList.back();
2416 WL->clear();
2417 WorkListFreeList.pop_back();
2418 }
2419 else {
2420 WL = new VisitorWorkList();
2421 WorkListCache.push_back(WL);
2422 }
2423 EnqueueWorkList(*WL, S);
2424 bool result = RunVisitorWorkList(*WL);
2425 WorkListFreeList.push_back(WL);
2426 return result;
2427}
2428
2429namespace {
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00002430typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002431RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2432 const DeclarationNameInfo &NI,
2433 const SourceRange &QLoc,
2434 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2435 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2436 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2437 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2438
2439 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2440
2441 RefNamePieces Pieces;
2442
2443 if (WantQualifier && QLoc.isValid())
2444 Pieces.push_back(QLoc);
2445
2446 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2447 Pieces.push_back(NI.getLoc());
2448
2449 if (WantTemplateArgs && TemplateArgs)
2450 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2451 TemplateArgs->RAngleLoc));
2452
2453 if (Kind == DeclarationName::CXXOperatorName) {
2454 Pieces.push_back(SourceLocation::getFromRawEncoding(
2455 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2456 Pieces.push_back(SourceLocation::getFromRawEncoding(
2457 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2458 }
2459
2460 if (WantSinglePiece) {
2461 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2462 Pieces.clear();
2463 Pieces.push_back(R);
2464 }
2465
2466 return Pieces;
2467}
2468}
2469
2470//===----------------------------------------------------------------------===//
2471// Misc. API hooks.
2472//===----------------------------------------------------------------------===//
2473
2474static llvm::sys::Mutex EnableMultithreadingMutex;
2475static bool EnabledMultithreading;
2476
Chad Rosier90836282013-03-27 18:28:23 +00002477static void fatal_error_handler(void *user_data, const std::string& reason,
2478 bool gen_crash_diag) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002479 // Write the result out to stderr avoiding errs() because raw_ostreams can
2480 // call report_fatal_error.
2481 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2482 ::abort();
2483}
2484
2485extern "C" {
2486CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2487 int displayDiagnostics) {
2488 // Disable pretty stack trace functionality, which will otherwise be a very
2489 // poor citizen of the world and set up all sorts of signal handlers.
2490 llvm::DisablePrettyStackTrace = true;
2491
2492 // We use crash recovery to make some of our APIs more reliable, implicitly
2493 // enable it.
2494 llvm::CrashRecoveryContext::Enable();
2495
2496 // Enable support for multithreading in LLVM.
2497 {
2498 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2499 if (!EnabledMultithreading) {
2500 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2501 llvm::llvm_start_multithreaded();
2502 EnabledMultithreading = true;
2503 }
2504 }
2505
2506 CIndexer *CIdxr = new CIndexer();
2507 if (excludeDeclarationsFromPCH)
2508 CIdxr->setOnlyLocalDecls();
2509 if (displayDiagnostics)
2510 CIdxr->setDisplayDiagnostics();
2511
2512 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2513 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2514 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2515 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2516 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2517 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2518
2519 return CIdxr;
2520}
2521
2522void clang_disposeIndex(CXIndex CIdx) {
2523 if (CIdx)
2524 delete static_cast<CIndexer *>(CIdx);
2525}
2526
2527void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2528 if (CIdx)
2529 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2530}
2531
2532unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2533 if (CIdx)
2534 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2535 return 0;
2536}
2537
2538void clang_toggleCrashRecovery(unsigned isEnabled) {
2539 if (isEnabled)
2540 llvm::CrashRecoveryContext::Enable();
2541 else
2542 llvm::CrashRecoveryContext::Disable();
2543}
2544
2545CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2546 const char *ast_filename) {
Argyrios Kyrtzidis4c9f58f2013-05-24 22:24:07 +00002547 if (!CIdx || !ast_filename)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002548 return 0;
2549
Argyrios Kyrtzidis4c9f58f2013-05-24 22:24:07 +00002550 LOG_FUNC_SECTION {
2551 *Log << ast_filename;
2552 }
2553
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002554 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2555 FileSystemOptions FileSystemOpts;
2556
2557 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2558 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2559 CXXIdx->getOnlyLocalDecls(),
2560 0, 0,
2561 /*CaptureDiagnostics=*/true,
2562 /*AllowPCHWithCompilerErrors=*/true,
2563 /*UserFilesAreVolatile=*/true);
2564 return MakeCXTranslationUnit(CXXIdx, TU);
2565}
2566
2567unsigned clang_defaultEditingTranslationUnitOptions() {
2568 return CXTranslationUnit_PrecompiledPreamble |
2569 CXTranslationUnit_CacheCompletionResults;
2570}
2571
2572CXTranslationUnit
2573clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2574 const char *source_filename,
2575 int num_command_line_args,
2576 const char * const *command_line_args,
2577 unsigned num_unsaved_files,
2578 struct CXUnsavedFile *unsaved_files) {
2579 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2580 return clang_parseTranslationUnit(CIdx, source_filename,
2581 command_line_args, num_command_line_args,
2582 unsaved_files, num_unsaved_files,
2583 Options);
2584}
2585
2586struct ParseTranslationUnitInfo {
2587 CXIndex CIdx;
2588 const char *source_filename;
2589 const char *const *command_line_args;
2590 int num_command_line_args;
2591 struct CXUnsavedFile *unsaved_files;
2592 unsigned num_unsaved_files;
2593 unsigned options;
2594 CXTranslationUnit result;
2595};
2596static void clang_parseTranslationUnit_Impl(void *UserData) {
2597 ParseTranslationUnitInfo *PTUI =
2598 static_cast<ParseTranslationUnitInfo*>(UserData);
2599 CXIndex CIdx = PTUI->CIdx;
2600 const char *source_filename = PTUI->source_filename;
2601 const char * const *command_line_args = PTUI->command_line_args;
2602 int num_command_line_args = PTUI->num_command_line_args;
2603 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2604 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2605 unsigned options = PTUI->options;
2606 PTUI->result = 0;
2607
2608 if (!CIdx)
2609 return;
2610
2611 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2612
2613 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2614 setThreadBackgroundPriority();
2615
2616 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2617 // FIXME: Add a flag for modules.
2618 TranslationUnitKind TUKind
2619 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
2620 bool CacheCodeCompetionResults
2621 = options & CXTranslationUnit_CacheCompletionResults;
2622 bool IncludeBriefCommentsInCodeCompletion
2623 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2624 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2625 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2626
2627 // Configure the diagnostics.
2628 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvad47afb92013-01-20 01:58:28 +00002629 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002630
2631 // Recover resources if we crash before exiting this function.
2632 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2633 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2634 DiagCleanup(Diags.getPtr());
2635
2636 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2637 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2638
2639 // Recover resources if we crash before exiting this function.
2640 llvm::CrashRecoveryContextCleanupRegistrar<
2641 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2642
2643 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2644 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2645 const llvm::MemoryBuffer *Buffer
2646 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2647 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2648 Buffer));
2649 }
2650
2651 OwningPtr<std::vector<const char *> >
2652 Args(new std::vector<const char*>());
2653
2654 // Recover resources if we crash before exiting this method.
2655 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2656 ArgsCleanup(Args.get());
2657
2658 // Since the Clang C library is primarily used by batch tools dealing with
2659 // (often very broken) source code, where spell-checking can have a
2660 // significant negative impact on performance (particularly when
2661 // precompiled headers are involved), we disable it by default.
2662 // Only do this if we haven't found a spell-checking-related argument.
2663 bool FoundSpellCheckingArgument = false;
2664 for (int I = 0; I != num_command_line_args; ++I) {
2665 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2666 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2667 FoundSpellCheckingArgument = true;
2668 break;
2669 }
2670 }
2671 if (!FoundSpellCheckingArgument)
2672 Args->push_back("-fno-spell-checking");
2673
2674 Args->insert(Args->end(), command_line_args,
2675 command_line_args + num_command_line_args);
2676
2677 // The 'source_filename' argument is optional. If the caller does not
2678 // specify it then it is assumed that the source file is specified
2679 // in the actual argument list.
2680 // Put the source file after command_line_args otherwise if '-x' flag is
2681 // present it will be unused.
2682 if (source_filename)
2683 Args->push_back(source_filename);
2684
2685 // Do we need the detailed preprocessing record?
2686 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2687 Args->push_back("-Xclang");
2688 Args->push_back("-detailed-preprocessing-record");
2689 }
2690
2691 unsigned NumErrors = Diags->getClient()->getNumErrors();
2692 OwningPtr<ASTUnit> ErrUnit;
2693 OwningPtr<ASTUnit> Unit(
2694 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2695 /* vector::data() not portable */,
2696 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2697 Diags,
2698 CXXIdx->getClangResourcesPath(),
2699 CXXIdx->getOnlyLocalDecls(),
2700 /*CaptureDiagnostics=*/true,
2701 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
2702 RemappedFiles->size(),
2703 /*RemappedFilesKeepOriginalName=*/true,
2704 PrecompilePreamble,
2705 TUKind,
2706 CacheCodeCompetionResults,
2707 IncludeBriefCommentsInCodeCompletion,
2708 /*AllowPCHWithCompilerErrors=*/true,
2709 SkipFunctionBodies,
2710 /*UserFilesAreVolatile=*/true,
2711 ForSerialization,
2712 &ErrUnit));
2713
2714 if (NumErrors != Diags->getClient()->getNumErrors()) {
2715 // Make sure to check that 'Unit' is non-NULL.
2716 if (CXXIdx->getDisplayDiagnostics())
2717 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2718 }
2719
2720 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2721}
2722CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2723 const char *source_filename,
2724 const char * const *command_line_args,
2725 int num_command_line_args,
2726 struct CXUnsavedFile *unsaved_files,
2727 unsigned num_unsaved_files,
2728 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002729 LOG_FUNC_SECTION {
2730 *Log << source_filename << ": ";
2731 for (int i = 0; i != num_command_line_args; ++i)
2732 *Log << command_line_args[i] << " ";
2733 }
2734
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002735 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2736 num_command_line_args, unsaved_files,
2737 num_unsaved_files, options, 0 };
2738 llvm::CrashRecoveryContext CRC;
2739
2740 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2741 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2742 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2743 fprintf(stderr, " 'command_line_args' : [");
2744 for (int i = 0; i != num_command_line_args; ++i) {
2745 if (i)
2746 fprintf(stderr, ", ");
2747 fprintf(stderr, "'%s'", command_line_args[i]);
2748 }
2749 fprintf(stderr, "],\n");
2750 fprintf(stderr, " 'unsaved_files' : [");
2751 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2752 if (i)
2753 fprintf(stderr, ", ");
2754 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2755 unsaved_files[i].Length);
2756 }
2757 fprintf(stderr, "],\n");
2758 fprintf(stderr, " 'options' : %d,\n", options);
2759 fprintf(stderr, "}\n");
2760
2761 return 0;
2762 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2763 PrintLibclangResourceUsage(PTUI.result);
2764 }
2765
2766 return PTUI.result;
2767}
2768
2769unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2770 return CXSaveTranslationUnit_None;
2771}
2772
2773namespace {
2774
2775struct SaveTranslationUnitInfo {
2776 CXTranslationUnit TU;
2777 const char *FileName;
2778 unsigned options;
2779 CXSaveError result;
2780};
2781
2782}
2783
2784static void clang_saveTranslationUnit_Impl(void *UserData) {
2785 SaveTranslationUnitInfo *STUI =
2786 static_cast<SaveTranslationUnitInfo*>(UserData);
2787
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002788 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002789 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2790 setThreadBackgroundPriority();
2791
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002792 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002793 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2794}
2795
2796int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2797 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002798 LOG_FUNC_SECTION {
2799 *Log << TU << ' ' << FileName;
2800 }
2801
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002802 if (!TU)
2803 return CXSaveError_InvalidTU;
2804
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002805 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002806 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2807 if (!CXXUnit->hasSema())
2808 return CXSaveError_InvalidTU;
2809
2810 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2811
2812 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2813 getenv("LIBCLANG_NOTHREADS")) {
2814 clang_saveTranslationUnit_Impl(&STUI);
2815
2816 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2817 PrintLibclangResourceUsage(TU);
2818
2819 return STUI.result;
2820 }
2821
2822 // We have an AST that has invalid nodes due to compiler errors.
2823 // Use a crash recovery thread for protection.
2824
2825 llvm::CrashRecoveryContext CRC;
2826
2827 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2828 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2829 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2830 fprintf(stderr, " 'options' : %d,\n", options);
2831 fprintf(stderr, "}\n");
2832
2833 return CXSaveError_Unknown;
2834
2835 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2836 PrintLibclangResourceUsage(TU);
2837 }
2838
2839 return STUI.result;
2840}
2841
2842void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2843 if (CTUnit) {
2844 // If the translation unit has been marked as unsafe to free, just discard
2845 // it.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002846 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002847 return;
2848
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002849 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenko9c48d162013-01-26 22:44:19 +00002850 delete CTUnit->StringPool;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002851 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2852 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko337ee242013-01-26 21:39:50 +00002853 delete CTUnit->FormatContext;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002854 delete CTUnit;
2855 }
2856}
2857
2858unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2859 return CXReparse_None;
2860}
2861
2862struct ReparseTranslationUnitInfo {
2863 CXTranslationUnit TU;
2864 unsigned num_unsaved_files;
2865 struct CXUnsavedFile *unsaved_files;
2866 unsigned options;
2867 int result;
2868};
2869
2870static void clang_reparseTranslationUnit_Impl(void *UserData) {
2871 ReparseTranslationUnitInfo *RTUI =
2872 static_cast<ReparseTranslationUnitInfo*>(UserData);
2873 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisd7bf4a42013-01-16 18:13:00 +00002874 if (!TU)
2875 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002876
2877 // Reset the associated diagnostics.
2878 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2879 TU->Diagnostics = 0;
2880
2881 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2882 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2883 unsigned options = RTUI->options;
2884 (void) options;
2885 RTUI->result = 1;
2886
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002887 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002888 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2889 setThreadBackgroundPriority();
2890
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002891 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002892 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2893
2894 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2895 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2896
2897 // Recover resources if we crash before exiting this function.
2898 llvm::CrashRecoveryContextCleanupRegistrar<
2899 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2900
2901 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2902 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2903 const llvm::MemoryBuffer *Buffer
2904 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2905 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2906 Buffer));
2907 }
2908
2909 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2910 RemappedFiles->size()))
2911 RTUI->result = 0;
2912}
2913
2914int clang_reparseTranslationUnit(CXTranslationUnit TU,
2915 unsigned num_unsaved_files,
2916 struct CXUnsavedFile *unsaved_files,
2917 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002918 LOG_FUNC_SECTION {
2919 *Log << TU;
2920 }
2921
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002922 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2923 options, 0 };
2924
2925 if (getenv("LIBCLANG_NOTHREADS")) {
2926 clang_reparseTranslationUnit_Impl(&RTUI);
2927 return RTUI.result;
2928 }
2929
2930 llvm::CrashRecoveryContext CRC;
2931
2932 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2933 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002934 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002935 return 1;
2936 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2937 PrintLibclangResourceUsage(TU);
2938
2939 return RTUI.result;
2940}
2941
2942
2943CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
2944 if (!CTUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00002945 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002946
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002947 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00002948 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002949}
2950
2951CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00002952 if (!TU)
2953 return clang_getNullCursor();
2954
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002955 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002956 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
2957}
2958
2959} // end: extern "C"
2960
2961//===----------------------------------------------------------------------===//
2962// CXFile Operations.
2963//===----------------------------------------------------------------------===//
2964
2965extern "C" {
2966CXString clang_getFileName(CXFile SFile) {
2967 if (!SFile)
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00002968 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002969
2970 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00002971 return cxstring::createRef(FEnt->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002972}
2973
2974time_t clang_getFileTime(CXFile SFile) {
2975 if (!SFile)
2976 return 0;
2977
2978 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2979 return FEnt->getModificationTime();
2980}
2981
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002982CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
2983 if (!TU)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002984 return 0;
2985
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002986 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002987
2988 FileManager &FMgr = CXXUnit->getFileManager();
2989 return const_cast<FileEntry *>(FMgr.getFile(file_name));
2990}
2991
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002992unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
2993 if (!TU || !file)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002994 return 0;
2995
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002996 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002997 FileEntry *FEnt = static_cast<FileEntry *>(file);
2998 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
2999 .isFileMultipleIncludeGuarded(FEnt);
3000}
3001
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003002int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3003 if (!file || !outID)
3004 return 1;
3005
3006#ifdef LLVM_ON_WIN32
3007 return 1; // inodes not supported on windows.
3008#else
3009 FileEntry *FEnt = static_cast<FileEntry *>(file);
3010 outID->data[0] = FEnt->getDevice();
3011 outID->data[1] = FEnt->getInode();
3012 outID->data[2] = FEnt->getModificationTime();
3013 return 0;
3014#endif
3015}
3016
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003017} // end: extern "C"
3018
3019//===----------------------------------------------------------------------===//
3020// CXCursor Operations.
3021//===----------------------------------------------------------------------===//
3022
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003023static const Decl *getDeclFromExpr(const Stmt *E) {
3024 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003025 return getDeclFromExpr(CE->getSubExpr());
3026
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003027 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003028 return RefExpr->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003029 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003030 return ME->getMemberDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003031 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003032 return RE->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003033 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003034 if (PRE->isExplicitProperty())
3035 return PRE->getExplicitProperty();
3036 // It could be messaging both getter and setter as in:
3037 // ++myobj.myprop;
3038 // in which case prefer to associate the setter since it is less obvious
3039 // from inspecting the source that the setter is going to get called.
3040 if (PRE->isMessagingSetter())
3041 return PRE->getImplicitPropertySetter();
3042 return PRE->getImplicitPropertyGetter();
3043 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003044 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003045 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003046 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003047 if (Expr *Src = OVE->getSourceExpr())
3048 return getDeclFromExpr(Src);
3049
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003050 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003051 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003052 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003053 if (!CE->isElidable())
3054 return CE->getConstructor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003055 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003056 return OME->getMethodDecl();
3057
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003058 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003059 return PE->getProtocol();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003060 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003061 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3062 return NTTP->getParameterPack();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003063 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003064 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3065 isa<ParmVarDecl>(SizeOfPack->getPack()))
3066 return SizeOfPack->getPack();
3067
3068 return 0;
3069}
3070
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003071static SourceLocation getLocationFromExpr(const Expr *E) {
3072 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003073 return getLocationFromExpr(CE->getSubExpr());
3074
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003075 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003076 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003077 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003078 return DRE->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003079 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003080 return Member->getMemberLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003081 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003082 return Ivar->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003083 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003084 return SizeOfPack->getPackLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003085 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003086 return PropRef->getLocation();
3087
3088 return E->getLocStart();
3089}
3090
3091extern "C" {
3092
3093unsigned clang_visitChildren(CXCursor parent,
3094 CXCursorVisitor visitor,
3095 CXClientData client_data) {
3096 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3097 /*VisitPreprocessorLast=*/false);
3098 return CursorVis.VisitChildren(parent);
3099}
3100
3101#ifndef __has_feature
3102#define __has_feature(x) 0
3103#endif
3104#if __has_feature(blocks)
3105typedef enum CXChildVisitResult
3106 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3107
3108static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3109 CXClientData client_data) {
3110 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3111 return block(cursor, parent);
3112}
3113#else
3114// If we are compiled with a compiler that doesn't have native blocks support,
3115// define and call the block manually, so the
3116typedef struct _CXChildVisitResult
3117{
3118 void *isa;
3119 int flags;
3120 int reserved;
3121 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3122 CXCursor);
3123} *CXCursorVisitorBlock;
3124
3125static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3126 CXClientData client_data) {
3127 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3128 return block->invoke(block, cursor, parent);
3129}
3130#endif
3131
3132
3133unsigned clang_visitChildrenWithBlock(CXCursor parent,
3134 CXCursorVisitorBlock block) {
3135 return clang_visitChildren(parent, visitWithBlock, block);
3136}
3137
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003138static CXString getDeclSpelling(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003139 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003140 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003141
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003142 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003143 if (!ND) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003144 if (const ObjCPropertyImplDecl *PropImpl =
3145 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003146 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003147 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003148
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003149 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003150 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003151 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003152
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003153 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003154 }
3155
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003156 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003157 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003158
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003159 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003160 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3161 // and returns different names. NamedDecl returns the class name and
3162 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003163 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003164
3165 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003166 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003167
3168 SmallString<1024> S;
3169 llvm::raw_svector_ostream os(S);
3170 ND->printName(os);
3171
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003172 return cxstring::createDup(os.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003173}
3174
3175CXString clang_getCursorSpelling(CXCursor C) {
3176 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko46f92522013-01-11 19:28:44 +00003177 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003178
3179 if (clang_isReference(C.kind)) {
3180 switch (C.kind) {
3181 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003182 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003183 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003184 }
3185 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003186 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003187 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003188 }
3189 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003190 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003191 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003192 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003193 }
3194 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003195 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003196 return cxstring::createDup(B->getType().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003197 }
3198 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003199 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003200 assert(Type && "Missing type decl");
3201
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003202 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003203 getAsString());
3204 }
3205 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003206 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003207 assert(Template && "Missing template decl");
3208
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003209 return cxstring::createDup(Template->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003210 }
3211
3212 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003213 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003214 assert(NS && "Missing namespace decl");
3215
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003216 return cxstring::createDup(NS->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003217 }
3218
3219 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003220 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003221 assert(Field && "Missing member decl");
3222
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003223 return cxstring::createDup(Field->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003224 }
3225
3226 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003227 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003228 assert(Label && "Missing label");
3229
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003230 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003231 }
3232
3233 case CXCursor_OverloadedDeclRef: {
3234 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003235 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3236 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003237 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003238 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003239 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003240 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003241 return cxstring::createDup(E->getName().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003242 OverloadedTemplateStorage *Ovl
3243 = Storage.get<OverloadedTemplateStorage*>();
3244 if (Ovl->size() == 0)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003245 return cxstring::createEmpty();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003246 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003247 }
3248
3249 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003250 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003251 assert(Var && "Missing variable decl");
3252
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003253 return cxstring::createDup(Var->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003254 }
3255
3256 default:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003257 return cxstring::createRef("<not implemented>");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003258 }
3259 }
3260
3261 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003262 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003263 if (D)
3264 return getDeclSpelling(D);
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003265 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003266 }
3267
3268 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003269 const Stmt *S = getCursorStmt(C);
3270 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003271 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003272
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003273 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003274 }
3275
3276 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003277 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003278 ->getNameStart());
3279
3280 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003281 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003282 ->getNameStart());
3283
3284 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003285 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003286
3287 if (clang_isDeclaration(C.kind))
3288 return getDeclSpelling(getCursorDecl(C));
3289
3290 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003291 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003292 return cxstring::createDup(AA->getAnnotation());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003293 }
3294
3295 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003296 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003297 return cxstring::createDup(AA->getLabel());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003298 }
3299
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003300 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003301}
3302
3303CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3304 unsigned pieceIndex,
3305 unsigned options) {
3306 if (clang_Cursor_isNull(C))
3307 return clang_getNullRange();
3308
3309 ASTContext &Ctx = getCursorContext(C);
3310
3311 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003312 const Stmt *S = getCursorStmt(C);
3313 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003314 if (pieceIndex > 0)
3315 return clang_getNullRange();
3316 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3317 }
3318
3319 return clang_getNullRange();
3320 }
3321
3322 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003323 if (const ObjCMessageExpr *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003324 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3325 if (pieceIndex >= ME->getNumSelectorLocs())
3326 return clang_getNullRange();
3327 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3328 }
3329 }
3330
3331 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3332 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003333 if (const ObjCMethodDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003334 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3335 if (pieceIndex >= MD->getNumSelectorLocs())
3336 return clang_getNullRange();
3337 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3338 }
3339 }
3340
3341 if (C.kind == CXCursor_ObjCCategoryDecl ||
3342 C.kind == CXCursor_ObjCCategoryImplDecl) {
3343 if (pieceIndex > 0)
3344 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003345 if (const ObjCCategoryDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003346 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3347 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003348 if (const ObjCCategoryImplDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003349 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3350 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3351 }
3352
3353 if (C.kind == CXCursor_ModuleImportDecl) {
3354 if (pieceIndex > 0)
3355 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003356 if (const ImportDecl *ImportD =
3357 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003358 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3359 if (!Locs.empty())
3360 return cxloc::translateSourceRange(Ctx,
3361 SourceRange(Locs.front(), Locs.back()));
3362 }
3363 return clang_getNullRange();
3364 }
3365
3366 // FIXME: A CXCursor_InclusionDirective should give the location of the
3367 // filename, but we don't keep track of this.
3368
3369 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3370 // but we don't keep track of this.
3371
3372 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3373 // but we don't keep track of this.
3374
3375 // Default handling, give the location of the cursor.
3376
3377 if (pieceIndex > 0)
3378 return clang_getNullRange();
3379
3380 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3381 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3382 return cxloc::translateSourceRange(Ctx, Loc);
3383}
3384
3385CXString clang_getCursorDisplayName(CXCursor C) {
3386 if (!clang_isDeclaration(C.kind))
3387 return clang_getCursorSpelling(C);
3388
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003389 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003390 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003391 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003392
3393 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003394 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003395 D = FunTmpl->getTemplatedDecl();
3396
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003397 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003398 SmallString<64> Str;
3399 llvm::raw_svector_ostream OS(Str);
3400 OS << *Function;
3401 if (Function->getPrimaryTemplate())
3402 OS << "<>";
3403 OS << "(";
3404 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3405 if (I)
3406 OS << ", ";
3407 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3408 }
3409
3410 if (Function->isVariadic()) {
3411 if (Function->getNumParams())
3412 OS << ", ";
3413 OS << "...";
3414 }
3415 OS << ")";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003416 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003417 }
3418
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003419 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003420 SmallString<64> Str;
3421 llvm::raw_svector_ostream OS(Str);
3422 OS << *ClassTemplate;
3423 OS << "<";
3424 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3425 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3426 if (I)
3427 OS << ", ";
3428
3429 NamedDecl *Param = Params->getParam(I);
3430 if (Param->getIdentifier()) {
3431 OS << Param->getIdentifier()->getName();
3432 continue;
3433 }
3434
3435 // There is no parameter name, which makes this tricky. Try to come up
3436 // with something useful that isn't too long.
3437 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3438 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3439 else if (NonTypeTemplateParmDecl *NTTP
3440 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3441 OS << NTTP->getType().getAsString(Policy);
3442 else
3443 OS << "template<...> class";
3444 }
3445
3446 OS << ">";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003447 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003448 }
3449
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003450 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003451 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3452 // If the type was explicitly written, use that.
3453 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003454 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003455
Benjamin Kramer5eada842013-02-22 15:46:01 +00003456 SmallString<128> Str;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003457 llvm::raw_svector_ostream OS(Str);
3458 OS << *ClassSpec;
Benjamin Kramer5eada842013-02-22 15:46:01 +00003459 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003460 ClassSpec->getTemplateArgs().data(),
3461 ClassSpec->getTemplateArgs().size(),
3462 Policy);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003463 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003464 }
3465
3466 return clang_getCursorSpelling(C);
3467}
3468
3469CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3470 switch (Kind) {
3471 case CXCursor_FunctionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003472 return cxstring::createRef("FunctionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003473 case CXCursor_TypedefDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003474 return cxstring::createRef("TypedefDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003475 case CXCursor_EnumDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003476 return cxstring::createRef("EnumDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003477 case CXCursor_EnumConstantDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003478 return cxstring::createRef("EnumConstantDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003479 case CXCursor_StructDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003480 return cxstring::createRef("StructDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003481 case CXCursor_UnionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003482 return cxstring::createRef("UnionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003483 case CXCursor_ClassDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003484 return cxstring::createRef("ClassDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003485 case CXCursor_FieldDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003486 return cxstring::createRef("FieldDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003487 case CXCursor_VarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003488 return cxstring::createRef("VarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003489 case CXCursor_ParmDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003490 return cxstring::createRef("ParmDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003491 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003492 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003493 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003494 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003495 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003496 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003497 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003498 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003499 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003500 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003501 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003502 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003503 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003504 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003505 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003506 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003507 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003508 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003509 case CXCursor_CXXMethod:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003510 return cxstring::createRef("CXXMethod");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003511 case CXCursor_UnexposedDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003512 return cxstring::createRef("UnexposedDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003513 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003514 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003515 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003516 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003517 case CXCursor_ObjCClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003518 return cxstring::createRef("ObjCClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003519 case CXCursor_TypeRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003520 return cxstring::createRef("TypeRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003521 case CXCursor_TemplateRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003522 return cxstring::createRef("TemplateRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003523 case CXCursor_NamespaceRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003524 return cxstring::createRef("NamespaceRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003525 case CXCursor_MemberRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003526 return cxstring::createRef("MemberRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003527 case CXCursor_LabelRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003528 return cxstring::createRef("LabelRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003529 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003530 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003531 case CXCursor_VariableRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003532 return cxstring::createRef("VariableRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003533 case CXCursor_IntegerLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003534 return cxstring::createRef("IntegerLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003535 case CXCursor_FloatingLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003536 return cxstring::createRef("FloatingLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003537 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003538 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003539 case CXCursor_StringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003540 return cxstring::createRef("StringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003541 case CXCursor_CharacterLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003542 return cxstring::createRef("CharacterLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003543 case CXCursor_ParenExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003544 return cxstring::createRef("ParenExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003545 case CXCursor_UnaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003546 return cxstring::createRef("UnaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003547 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003548 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003549 case CXCursor_BinaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003550 return cxstring::createRef("BinaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003551 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003552 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003553 case CXCursor_ConditionalOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003554 return cxstring::createRef("ConditionalOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003555 case CXCursor_CStyleCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003556 return cxstring::createRef("CStyleCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003557 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003558 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003559 case CXCursor_InitListExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003560 return cxstring::createRef("InitListExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003561 case CXCursor_AddrLabelExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003562 return cxstring::createRef("AddrLabelExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003563 case CXCursor_StmtExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003564 return cxstring::createRef("StmtExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003565 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003566 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003567 case CXCursor_GNUNullExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003568 return cxstring::createRef("GNUNullExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003569 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003570 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003571 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003572 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003573 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003574 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003575 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003576 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003577 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003578 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003579 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003580 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003581 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003582 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003583 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003584 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003585 case CXCursor_CXXThisExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003586 return cxstring::createRef("CXXThisExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003587 case CXCursor_CXXThrowExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003588 return cxstring::createRef("CXXThrowExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003589 case CXCursor_CXXNewExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003590 return cxstring::createRef("CXXNewExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003591 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003592 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003593 case CXCursor_UnaryExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003594 return cxstring::createRef("UnaryExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003595 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003596 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003597 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003598 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisedab0472013-04-23 17:57:17 +00003599 case CXCursor_ObjCSelfExpr:
3600 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003601 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003602 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003603 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003604 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003605 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003606 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003607 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003608 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003609 case CXCursor_BlockExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003610 return cxstring::createRef("BlockExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003611 case CXCursor_PackExpansionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003612 return cxstring::createRef("PackExpansionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003613 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003614 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003615 case CXCursor_LambdaExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003616 return cxstring::createRef("LambdaExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003617 case CXCursor_UnexposedExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003618 return cxstring::createRef("UnexposedExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003619 case CXCursor_DeclRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003620 return cxstring::createRef("DeclRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003621 case CXCursor_MemberRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003622 return cxstring::createRef("MemberRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003623 case CXCursor_CallExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003624 return cxstring::createRef("CallExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003625 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003626 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003627 case CXCursor_UnexposedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003628 return cxstring::createRef("UnexposedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003629 case CXCursor_DeclStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003630 return cxstring::createRef("DeclStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003631 case CXCursor_LabelStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003632 return cxstring::createRef("LabelStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003633 case CXCursor_CompoundStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003634 return cxstring::createRef("CompoundStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003635 case CXCursor_CaseStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003636 return cxstring::createRef("CaseStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003637 case CXCursor_DefaultStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003638 return cxstring::createRef("DefaultStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003639 case CXCursor_IfStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003640 return cxstring::createRef("IfStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003641 case CXCursor_SwitchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003642 return cxstring::createRef("SwitchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003643 case CXCursor_WhileStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003644 return cxstring::createRef("WhileStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003645 case CXCursor_DoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003646 return cxstring::createRef("DoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003647 case CXCursor_ForStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003648 return cxstring::createRef("ForStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003649 case CXCursor_GotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003650 return cxstring::createRef("GotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003651 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003652 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003653 case CXCursor_ContinueStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003654 return cxstring::createRef("ContinueStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003655 case CXCursor_BreakStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003656 return cxstring::createRef("BreakStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003657 case CXCursor_ReturnStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003658 return cxstring::createRef("ReturnStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003659 case CXCursor_GCCAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003660 return cxstring::createRef("GCCAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003661 case CXCursor_MSAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003662 return cxstring::createRef("MSAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003663 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003664 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003665 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003666 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003667 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003668 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003669 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003670 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003671 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003672 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003673 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003674 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003675 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003676 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003677 case CXCursor_CXXCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003678 return cxstring::createRef("CXXCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003679 case CXCursor_CXXTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003680 return cxstring::createRef("CXXTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003681 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003682 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003683 case CXCursor_SEHTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003684 return cxstring::createRef("SEHTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003685 case CXCursor_SEHExceptStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003686 return cxstring::createRef("SEHExceptStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003687 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003688 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003689 case CXCursor_NullStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003690 return cxstring::createRef("NullStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003691 case CXCursor_InvalidFile:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003692 return cxstring::createRef("InvalidFile");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003693 case CXCursor_InvalidCode:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003694 return cxstring::createRef("InvalidCode");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003695 case CXCursor_NoDeclFound:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003696 return cxstring::createRef("NoDeclFound");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003697 case CXCursor_NotImplemented:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003698 return cxstring::createRef("NotImplemented");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003699 case CXCursor_TranslationUnit:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003700 return cxstring::createRef("TranslationUnit");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003701 case CXCursor_UnexposedAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003702 return cxstring::createRef("UnexposedAttr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003703 case CXCursor_IBActionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003704 return cxstring::createRef("attribute(ibaction)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003705 case CXCursor_IBOutletAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003706 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003707 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003708 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003709 case CXCursor_CXXFinalAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003710 return cxstring::createRef("attribute(final)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003711 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003712 return cxstring::createRef("attribute(override)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003713 case CXCursor_AnnotateAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003714 return cxstring::createRef("attribute(annotate)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003715 case CXCursor_AsmLabelAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003716 return cxstring::createRef("asm label");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003717 case CXCursor_PreprocessingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003718 return cxstring::createRef("preprocessing directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003719 case CXCursor_MacroDefinition:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003720 return cxstring::createRef("macro definition");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003721 case CXCursor_MacroExpansion:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003722 return cxstring::createRef("macro expansion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003723 case CXCursor_InclusionDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003724 return cxstring::createRef("inclusion directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003725 case CXCursor_Namespace:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003726 return cxstring::createRef("Namespace");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003727 case CXCursor_LinkageSpec:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003728 return cxstring::createRef("LinkageSpec");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003729 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003730 return cxstring::createRef("C++ base class specifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003731 case CXCursor_Constructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003732 return cxstring::createRef("CXXConstructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003733 case CXCursor_Destructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003734 return cxstring::createRef("CXXDestructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003735 case CXCursor_ConversionFunction:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003736 return cxstring::createRef("CXXConversion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003737 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003738 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003739 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003740 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003741 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003742 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003743 case CXCursor_FunctionTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003744 return cxstring::createRef("FunctionTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003745 case CXCursor_ClassTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003746 return cxstring::createRef("ClassTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003747 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003748 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003749 case CXCursor_NamespaceAlias:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003750 return cxstring::createRef("NamespaceAlias");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003751 case CXCursor_UsingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003752 return cxstring::createRef("UsingDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003753 case CXCursor_UsingDeclaration:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003754 return cxstring::createRef("UsingDeclaration");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003755 case CXCursor_TypeAliasDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003756 return cxstring::createRef("TypeAliasDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003757 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003758 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003759 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003760 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003761 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003762 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003763 case CXCursor_ModuleImportDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003764 return cxstring::createRef("ModuleImport");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003765 }
3766
3767 llvm_unreachable("Unhandled CXCursorKind");
3768}
3769
3770struct GetCursorData {
3771 SourceLocation TokenBeginLoc;
3772 bool PointsAtMacroArgExpansion;
3773 bool VisitedObjCPropertyImplDecl;
3774 SourceLocation VisitedDeclaratorDeclStartLoc;
3775 CXCursor &BestCursor;
3776
3777 GetCursorData(SourceManager &SM,
3778 SourceLocation tokenBegin, CXCursor &outputCursor)
3779 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3780 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3781 VisitedObjCPropertyImplDecl = false;
3782 }
3783};
3784
3785static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3786 CXCursor parent,
3787 CXClientData client_data) {
3788 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3789 CXCursor *BestCursor = &Data->BestCursor;
3790
3791 // If we point inside a macro argument we should provide info of what the
3792 // token is so use the actual cursor, don't replace it with a macro expansion
3793 // cursor.
3794 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3795 return CXChildVisit_Recurse;
3796
3797 if (clang_isDeclaration(cursor.kind)) {
3798 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003799 if (const ObjCMethodDecl *MD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003800 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3801 if (MD->isImplicit())
3802 return CXChildVisit_Break;
3803
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003804 } else if (const ObjCInterfaceDecl *ID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003805 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3806 // Check that when we have multiple @class references in the same line,
3807 // that later ones do not override the previous ones.
3808 // If we have:
3809 // @class Foo, Bar;
3810 // source ranges for both start at '@', so 'Bar' will end up overriding
3811 // 'Foo' even though the cursor location was at 'Foo'.
3812 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3813 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003814 if (const ObjCInterfaceDecl *PrevID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003815 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3816 if (PrevID != ID &&
3817 !PrevID->isThisDeclarationADefinition() &&
3818 !ID->isThisDeclarationADefinition())
3819 return CXChildVisit_Break;
3820 }
3821
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003822 } else if (const DeclaratorDecl *DD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003823 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3824 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3825 // Check that when we have multiple declarators in the same line,
3826 // that later ones do not override the previous ones.
3827 // If we have:
3828 // int Foo, Bar;
3829 // source ranges for both start at 'int', so 'Bar' will end up overriding
3830 // 'Foo' even though the cursor location was at 'Foo'.
3831 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3832 return CXChildVisit_Break;
3833 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3834
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003835 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003836 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3837 (void)PropImp;
3838 // Check that when we have multiple @synthesize in the same line,
3839 // that later ones do not override the previous ones.
3840 // If we have:
3841 // @synthesize Foo, Bar;
3842 // source ranges for both start at '@', so 'Bar' will end up overriding
3843 // 'Foo' even though the cursor location was at 'Foo'.
3844 if (Data->VisitedObjCPropertyImplDecl)
3845 return CXChildVisit_Break;
3846 Data->VisitedObjCPropertyImplDecl = true;
3847 }
3848 }
3849
3850 if (clang_isExpression(cursor.kind) &&
3851 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003852 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003853 // Avoid having the cursor of an expression replace the declaration cursor
3854 // when the expression source range overlaps the declaration range.
3855 // This can happen for C++ constructor expressions whose range generally
3856 // include the variable declaration, e.g.:
3857 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3858 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3859 D->getLocation() == Data->TokenBeginLoc)
3860 return CXChildVisit_Break;
3861 }
3862 }
3863
3864 // If our current best cursor is the construction of a temporary object,
3865 // don't replace that cursor with a type reference, because we want
3866 // clang_getCursor() to point at the constructor.
3867 if (clang_isExpression(BestCursor->kind) &&
3868 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3869 cursor.kind == CXCursor_TypeRef) {
3870 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3871 // as having the actual point on the type reference.
3872 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3873 return CXChildVisit_Recurse;
3874 }
3875
3876 *BestCursor = cursor;
3877 return CXChildVisit_Recurse;
3878}
3879
3880CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3881 if (!TU)
3882 return clang_getNullCursor();
3883
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003884 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003885 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3886
3887 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3888 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3889
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003890 LOG_FUNC_SECTION {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003891 CXFile SearchFile;
3892 unsigned SearchLine, SearchColumn;
3893 CXFile ResultFile;
3894 unsigned ResultLine, ResultColumn;
3895 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3896 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3897 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3898
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003899 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3900 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003901 &ResultColumn, 0);
3902 SearchFileName = clang_getFileName(SearchFile);
3903 ResultFileName = clang_getFileName(ResultFile);
3904 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3905 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003906 *Log << llvm::format("(%s:%d:%d) = %s",
3907 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3908 clang_getCString(KindSpelling))
3909 << llvm::format("(%s:%d:%d):%s%s",
3910 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3911 clang_getCString(USR), IsDef);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003912 clang_disposeString(SearchFileName);
3913 clang_disposeString(ResultFileName);
3914 clang_disposeString(KindSpelling);
3915 clang_disposeString(USR);
3916
3917 CXCursor Definition = clang_getCursorDefinition(Result);
3918 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3919 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3920 CXString DefinitionKindSpelling
3921 = clang_getCursorKindSpelling(Definition.kind);
3922 CXFile DefinitionFile;
3923 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003924 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003925 &DefinitionLine, &DefinitionColumn, 0);
3926 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003927 *Log << llvm::format(" -> %s(%s:%d:%d)",
3928 clang_getCString(DefinitionKindSpelling),
3929 clang_getCString(DefinitionFileName),
3930 DefinitionLine, DefinitionColumn);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003931 clang_disposeString(DefinitionFileName);
3932 clang_disposeString(DefinitionKindSpelling);
3933 }
3934 }
3935
3936 return Result;
3937}
3938
3939CXCursor clang_getNullCursor(void) {
3940 return MakeCXCursorInvalid(CXCursor_InvalidFile);
3941}
3942
3943unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisd1d9df62013-01-08 18:23:28 +00003944 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
3945 // can't set consistently. For example, when visiting a DeclStmt we will set
3946 // it but we don't set it on the result of clang_getCursorDefinition for
3947 // a reference of the same declaration.
3948 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
3949 // when visiting a DeclStmt currently, the AST should be enhanced to be able
3950 // to provide that kind of info.
3951 if (clang_isDeclaration(X.kind))
3952 X.data[1] = 0;
3953 if (clang_isDeclaration(Y.kind))
3954 Y.data[1] = 0;
3955
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003956 return X == Y;
3957}
3958
3959unsigned clang_hashCursor(CXCursor C) {
3960 unsigned Index = 0;
3961 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3962 Index = 1;
3963
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003964 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003965 std::make_pair(C.kind, C.data[Index]));
3966}
3967
3968unsigned clang_isInvalid(enum CXCursorKind K) {
3969 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3970}
3971
3972unsigned clang_isDeclaration(enum CXCursorKind K) {
3973 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
3974 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
3975}
3976
3977unsigned clang_isReference(enum CXCursorKind K) {
3978 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3979}
3980
3981unsigned clang_isExpression(enum CXCursorKind K) {
3982 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3983}
3984
3985unsigned clang_isStatement(enum CXCursorKind K) {
3986 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3987}
3988
3989unsigned clang_isAttribute(enum CXCursorKind K) {
3990 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
3991}
3992
3993unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3994 return K == CXCursor_TranslationUnit;
3995}
3996
3997unsigned clang_isPreprocessing(enum CXCursorKind K) {
3998 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3999}
4000
4001unsigned clang_isUnexposed(enum CXCursorKind K) {
4002 switch (K) {
4003 case CXCursor_UnexposedDecl:
4004 case CXCursor_UnexposedExpr:
4005 case CXCursor_UnexposedStmt:
4006 case CXCursor_UnexposedAttr:
4007 return true;
4008 default:
4009 return false;
4010 }
4011}
4012
4013CXCursorKind clang_getCursorKind(CXCursor C) {
4014 return C.kind;
4015}
4016
4017CXSourceLocation clang_getCursorLocation(CXCursor C) {
4018 if (clang_isReference(C.kind)) {
4019 switch (C.kind) {
4020 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004021 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004022 = getCursorObjCSuperClassRef(C);
4023 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4024 }
4025
4026 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004027 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004028 = getCursorObjCProtocolRef(C);
4029 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4030 }
4031
4032 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004033 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004034 = getCursorObjCClassRef(C);
4035 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4036 }
4037
4038 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004039 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004040 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4041 }
4042
4043 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004044 std::pair<const TemplateDecl *, SourceLocation> P =
4045 getCursorTemplateRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004046 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4047 }
4048
4049 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004050 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004051 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4052 }
4053
4054 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004055 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004056 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4057 }
4058
4059 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004060 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004061 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4062 }
4063
4064 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004065 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004066 if (!BaseSpec)
4067 return clang_getNullLocation();
4068
4069 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4070 return cxloc::translateSourceLocation(getCursorContext(C),
4071 TSInfo->getTypeLoc().getBeginLoc());
4072
4073 return cxloc::translateSourceLocation(getCursorContext(C),
4074 BaseSpec->getLocStart());
4075 }
4076
4077 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004078 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004079 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4080 }
4081
4082 case CXCursor_OverloadedDeclRef:
4083 return cxloc::translateSourceLocation(getCursorContext(C),
4084 getCursorOverloadedDeclRef(C).second);
4085
4086 default:
4087 // FIXME: Need a way to enumerate all non-reference cases.
4088 llvm_unreachable("Missed a reference kind");
4089 }
4090 }
4091
4092 if (clang_isExpression(C.kind))
4093 return cxloc::translateSourceLocation(getCursorContext(C),
4094 getLocationFromExpr(getCursorExpr(C)));
4095
4096 if (clang_isStatement(C.kind))
4097 return cxloc::translateSourceLocation(getCursorContext(C),
4098 getCursorStmt(C)->getLocStart());
4099
4100 if (C.kind == CXCursor_PreprocessingDirective) {
4101 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4102 return cxloc::translateSourceLocation(getCursorContext(C), L);
4103 }
4104
4105 if (C.kind == CXCursor_MacroExpansion) {
4106 SourceLocation L
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004107 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004108 return cxloc::translateSourceLocation(getCursorContext(C), L);
4109 }
4110
4111 if (C.kind == CXCursor_MacroDefinition) {
4112 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4113 return cxloc::translateSourceLocation(getCursorContext(C), L);
4114 }
4115
4116 if (C.kind == CXCursor_InclusionDirective) {
4117 SourceLocation L
4118 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4119 return cxloc::translateSourceLocation(getCursorContext(C), L);
4120 }
4121
4122 if (!clang_isDeclaration(C.kind))
4123 return clang_getNullLocation();
4124
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004125 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004126 if (!D)
4127 return clang_getNullLocation();
4128
4129 SourceLocation Loc = D->getLocation();
4130 // FIXME: Multiple variables declared in a single declaration
4131 // currently lack the information needed to correctly determine their
4132 // ranges when accounting for the type-specifier. We use context
4133 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4134 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004135 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004136 if (!cxcursor::isFirstInDeclGroup(C))
4137 Loc = VD->getLocation();
4138 }
4139
4140 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004141 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004142 Loc = MD->getSelectorStartLoc();
4143
4144 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4145}
4146
4147} // end extern "C"
4148
4149CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4150 assert(TU);
4151
4152 // Guard against an invalid SourceLocation, or we may assert in one
4153 // of the following calls.
4154 if (SLoc.isInvalid())
4155 return clang_getNullCursor();
4156
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004157 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004158
4159 // Translate the given source location to make it point at the beginning of
4160 // the token under the cursor.
4161 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4162 CXXUnit->getASTContext().getLangOpts());
4163
4164 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4165 if (SLoc.isValid()) {
4166 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4167 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4168 /*VisitPreprocessorLast=*/true,
4169 /*VisitIncludedEntities=*/false,
4170 SourceLocation(SLoc));
4171 CursorVis.visitFileRegion();
4172 }
4173
4174 return Result;
4175}
4176
4177static SourceRange getRawCursorExtent(CXCursor C) {
4178 if (clang_isReference(C.kind)) {
4179 switch (C.kind) {
4180 case CXCursor_ObjCSuperClassRef:
4181 return getCursorObjCSuperClassRef(C).second;
4182
4183 case CXCursor_ObjCProtocolRef:
4184 return getCursorObjCProtocolRef(C).second;
4185
4186 case CXCursor_ObjCClassRef:
4187 return getCursorObjCClassRef(C).second;
4188
4189 case CXCursor_TypeRef:
4190 return getCursorTypeRef(C).second;
4191
4192 case CXCursor_TemplateRef:
4193 return getCursorTemplateRef(C).second;
4194
4195 case CXCursor_NamespaceRef:
4196 return getCursorNamespaceRef(C).second;
4197
4198 case CXCursor_MemberRef:
4199 return getCursorMemberRef(C).second;
4200
4201 case CXCursor_CXXBaseSpecifier:
4202 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4203
4204 case CXCursor_LabelRef:
4205 return getCursorLabelRef(C).second;
4206
4207 case CXCursor_OverloadedDeclRef:
4208 return getCursorOverloadedDeclRef(C).second;
4209
4210 case CXCursor_VariableRef:
4211 return getCursorVariableRef(C).second;
4212
4213 default:
4214 // FIXME: Need a way to enumerate all non-reference cases.
4215 llvm_unreachable("Missed a reference kind");
4216 }
4217 }
4218
4219 if (clang_isExpression(C.kind))
4220 return getCursorExpr(C)->getSourceRange();
4221
4222 if (clang_isStatement(C.kind))
4223 return getCursorStmt(C)->getSourceRange();
4224
4225 if (clang_isAttribute(C.kind))
4226 return getCursorAttr(C)->getRange();
4227
4228 if (C.kind == CXCursor_PreprocessingDirective)
4229 return cxcursor::getCursorPreprocessingDirective(C);
4230
4231 if (C.kind == CXCursor_MacroExpansion) {
4232 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004233 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004234 return TU->mapRangeFromPreamble(Range);
4235 }
4236
4237 if (C.kind == CXCursor_MacroDefinition) {
4238 ASTUnit *TU = getCursorASTUnit(C);
4239 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4240 return TU->mapRangeFromPreamble(Range);
4241 }
4242
4243 if (C.kind == CXCursor_InclusionDirective) {
4244 ASTUnit *TU = getCursorASTUnit(C);
4245 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4246 return TU->mapRangeFromPreamble(Range);
4247 }
4248
4249 if (C.kind == CXCursor_TranslationUnit) {
4250 ASTUnit *TU = getCursorASTUnit(C);
4251 FileID MainID = TU->getSourceManager().getMainFileID();
4252 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4253 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4254 return SourceRange(Start, End);
4255 }
4256
4257 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004258 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004259 if (!D)
4260 return SourceRange();
4261
4262 SourceRange R = D->getSourceRange();
4263 // FIXME: Multiple variables declared in a single declaration
4264 // currently lack the information needed to correctly determine their
4265 // ranges when accounting for the type-specifier. We use context
4266 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4267 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004268 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004269 if (!cxcursor::isFirstInDeclGroup(C))
4270 R.setBegin(VD->getLocation());
4271 }
4272 return R;
4273 }
4274 return SourceRange();
4275}
4276
4277/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4278/// the decl-specifier-seq for declarations.
4279static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4280 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004281 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004282 if (!D)
4283 return SourceRange();
4284
4285 SourceRange R = D->getSourceRange();
4286
4287 // Adjust the start of the location for declarations preceded by
4288 // declaration specifiers.
4289 SourceLocation StartLoc;
4290 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4291 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4292 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004293 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004294 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4295 StartLoc = TI->getTypeLoc().getLocStart();
4296 }
4297
4298 if (StartLoc.isValid() && R.getBegin().isValid() &&
4299 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4300 R.setBegin(StartLoc);
4301
4302 // FIXME: Multiple variables declared in a single declaration
4303 // currently lack the information needed to correctly determine their
4304 // ranges when accounting for the type-specifier. We use context
4305 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4306 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004307 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004308 if (!cxcursor::isFirstInDeclGroup(C))
4309 R.setBegin(VD->getLocation());
4310 }
4311
4312 return R;
4313 }
4314
4315 return getRawCursorExtent(C);
4316}
4317
4318extern "C" {
4319
4320CXSourceRange clang_getCursorExtent(CXCursor C) {
4321 SourceRange R = getRawCursorExtent(C);
4322 if (R.isInvalid())
4323 return clang_getNullRange();
4324
4325 return cxloc::translateSourceRange(getCursorContext(C), R);
4326}
4327
4328CXCursor clang_getCursorReferenced(CXCursor C) {
4329 if (clang_isInvalid(C.kind))
4330 return clang_getNullCursor();
4331
4332 CXTranslationUnit tu = getCursorTU(C);
4333 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004334 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004335 if (!D)
4336 return clang_getNullCursor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004337 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004338 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004339 if (const ObjCPropertyImplDecl *PropImpl =
4340 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004341 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4342 return MakeCXCursor(Property, tu);
4343
4344 return C;
4345 }
4346
4347 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004348 const Expr *E = getCursorExpr(C);
4349 const Decl *D = getDeclFromExpr(E);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004350 if (D) {
4351 CXCursor declCursor = MakeCXCursor(D, tu);
4352 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4353 declCursor);
4354 return declCursor;
4355 }
4356
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004357 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004358 return MakeCursorOverloadedDeclRef(Ovl, tu);
4359
4360 return clang_getNullCursor();
4361 }
4362
4363 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004364 const Stmt *S = getCursorStmt(C);
4365 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004366 if (LabelDecl *label = Goto->getLabel())
4367 if (LabelStmt *labelS = label->getStmt())
4368 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4369
4370 return clang_getNullCursor();
4371 }
4372
4373 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004374 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004375 return MakeMacroDefinitionCursor(Def, tu);
4376 }
4377
4378 if (!clang_isReference(C.kind))
4379 return clang_getNullCursor();
4380
4381 switch (C.kind) {
4382 case CXCursor_ObjCSuperClassRef:
4383 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4384
4385 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004386 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4387 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004388 return MakeCXCursor(Def, tu);
4389
4390 return MakeCXCursor(Prot, tu);
4391 }
4392
4393 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004394 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4395 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004396 return MakeCXCursor(Def, tu);
4397
4398 return MakeCXCursor(Class, tu);
4399 }
4400
4401 case CXCursor_TypeRef:
4402 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4403
4404 case CXCursor_TemplateRef:
4405 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4406
4407 case CXCursor_NamespaceRef:
4408 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4409
4410 case CXCursor_MemberRef:
4411 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4412
4413 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004414 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004415 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4416 tu ));
4417 }
4418
4419 case CXCursor_LabelRef:
4420 // FIXME: We end up faking the "parent" declaration here because we
4421 // don't want to make CXCursor larger.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004422 return MakeCXCursor(getCursorLabelRef(C).first,
4423 cxtu::getASTUnit(tu)->getASTContext()
4424 .getTranslationUnitDecl(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004425 tu);
4426
4427 case CXCursor_OverloadedDeclRef:
4428 return C;
4429
4430 case CXCursor_VariableRef:
4431 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4432
4433 default:
4434 // We would prefer to enumerate all non-reference cursor kinds here.
4435 llvm_unreachable("Unhandled reference cursor kind");
4436 }
4437}
4438
4439CXCursor clang_getCursorDefinition(CXCursor C) {
4440 if (clang_isInvalid(C.kind))
4441 return clang_getNullCursor();
4442
4443 CXTranslationUnit TU = getCursorTU(C);
4444
4445 bool WasReference = false;
4446 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4447 C = clang_getCursorReferenced(C);
4448 WasReference = true;
4449 }
4450
4451 if (C.kind == CXCursor_MacroExpansion)
4452 return clang_getCursorReferenced(C);
4453
4454 if (!clang_isDeclaration(C.kind))
4455 return clang_getNullCursor();
4456
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004457 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004458 if (!D)
4459 return clang_getNullCursor();
4460
4461 switch (D->getKind()) {
4462 // Declaration kinds that don't really separate the notions of
4463 // declaration and definition.
4464 case Decl::Namespace:
4465 case Decl::Typedef:
4466 case Decl::TypeAlias:
4467 case Decl::TypeAliasTemplate:
4468 case Decl::TemplateTypeParm:
4469 case Decl::EnumConstant:
4470 case Decl::Field:
John McCall76da55d2013-04-16 07:28:30 +00004471 case Decl::MSProperty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004472 case Decl::IndirectField:
4473 case Decl::ObjCIvar:
4474 case Decl::ObjCAtDefsField:
4475 case Decl::ImplicitParam:
4476 case Decl::ParmVar:
4477 case Decl::NonTypeTemplateParm:
4478 case Decl::TemplateTemplateParm:
4479 case Decl::ObjCCategoryImpl:
4480 case Decl::ObjCImplementation:
4481 case Decl::AccessSpec:
4482 case Decl::LinkageSpec:
4483 case Decl::ObjCPropertyImpl:
4484 case Decl::FileScopeAsm:
4485 case Decl::StaticAssert:
4486 case Decl::Block:
Tareq A. Siraj6afcf882013-04-16 19:37:38 +00004487 case Decl::Captured:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004488 case Decl::Label: // FIXME: Is this right??
4489 case Decl::ClassScopeFunctionSpecialization:
4490 case Decl::Import:
Alexey Bataevc6400582013-03-22 06:34:35 +00004491 case Decl::OMPThreadPrivate:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004492 return C;
4493
4494 // Declaration kinds that don't make any sense here, but are
4495 // nonetheless harmless.
David Blaikief23546a2013-02-22 17:44:58 +00004496 case Decl::Empty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004497 case Decl::TranslationUnit:
4498 break;
4499
4500 // Declaration kinds for which the definition is not resolvable.
4501 case Decl::UnresolvedUsingTypename:
4502 case Decl::UnresolvedUsingValue:
4503 break;
4504
4505 case Decl::UsingDirective:
4506 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4507 TU);
4508
4509 case Decl::NamespaceAlias:
4510 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4511
4512 case Decl::Enum:
4513 case Decl::Record:
4514 case Decl::CXXRecord:
4515 case Decl::ClassTemplateSpecialization:
4516 case Decl::ClassTemplatePartialSpecialization:
4517 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4518 return MakeCXCursor(Def, TU);
4519 return clang_getNullCursor();
4520
4521 case Decl::Function:
4522 case Decl::CXXMethod:
4523 case Decl::CXXConstructor:
4524 case Decl::CXXDestructor:
4525 case Decl::CXXConversion: {
4526 const FunctionDecl *Def = 0;
4527 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko05756dc2013-01-14 00:46:27 +00004528 return MakeCXCursor(Def, TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004529 return clang_getNullCursor();
4530 }
4531
4532 case Decl::Var: {
4533 // Ask the variable if it has a definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004534 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004535 return MakeCXCursor(Def, TU);
4536 return clang_getNullCursor();
4537 }
4538
4539 case Decl::FunctionTemplate: {
4540 const FunctionDecl *Def = 0;
4541 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4542 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4543 return clang_getNullCursor();
4544 }
4545
4546 case Decl::ClassTemplate: {
4547 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4548 ->getDefinition())
4549 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4550 TU);
4551 return clang_getNullCursor();
4552 }
4553
4554 case Decl::Using:
4555 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4556 D->getLocation(), TU);
4557
4558 case Decl::UsingShadow:
4559 return clang_getCursorDefinition(
4560 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4561 TU));
4562
4563 case Decl::ObjCMethod: {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004564 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004565 if (Method->isThisDeclarationADefinition())
4566 return C;
4567
4568 // Dig out the method definition in the associated
4569 // @implementation, if we have it.
4570 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004571 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004572 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4573 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4574 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4575 Method->isInstanceMethod()))
4576 if (Def->isThisDeclarationADefinition())
4577 return MakeCXCursor(Def, TU);
4578
4579 return clang_getNullCursor();
4580 }
4581
4582 case Decl::ObjCCategory:
4583 if (ObjCCategoryImplDecl *Impl
4584 = cast<ObjCCategoryDecl>(D)->getImplementation())
4585 return MakeCXCursor(Impl, TU);
4586 return clang_getNullCursor();
4587
4588 case Decl::ObjCProtocol:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004589 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004590 return MakeCXCursor(Def, TU);
4591 return clang_getNullCursor();
4592
4593 case Decl::ObjCInterface: {
4594 // There are two notions of a "definition" for an Objective-C
4595 // class: the interface and its implementation. When we resolved a
4596 // reference to an Objective-C class, produce the @interface as
4597 // the definition; when we were provided with the interface,
4598 // produce the @implementation as the definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004599 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004600 if (WasReference) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004601 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004602 return MakeCXCursor(Def, TU);
4603 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4604 return MakeCXCursor(Impl, TU);
4605 return clang_getNullCursor();
4606 }
4607
4608 case Decl::ObjCProperty:
4609 // FIXME: We don't really know where to find the
4610 // ObjCPropertyImplDecls that implement this property.
4611 return clang_getNullCursor();
4612
4613 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004614 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004615 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004616 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004617 return MakeCXCursor(Def, TU);
4618
4619 return clang_getNullCursor();
4620
4621 case Decl::Friend:
4622 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4623 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4624 return clang_getNullCursor();
4625
4626 case Decl::FriendTemplate:
4627 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4628 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4629 return clang_getNullCursor();
4630 }
4631
4632 return clang_getNullCursor();
4633}
4634
4635unsigned clang_isCursorDefinition(CXCursor C) {
4636 if (!clang_isDeclaration(C.kind))
4637 return 0;
4638
4639 return clang_getCursorDefinition(C) == C;
4640}
4641
4642CXCursor clang_getCanonicalCursor(CXCursor C) {
4643 if (!clang_isDeclaration(C.kind))
4644 return C;
4645
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004646 if (const Decl *D = getCursorDecl(C)) {
4647 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004648 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4649 return MakeCXCursor(CatD, getCursorTU(C));
4650
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004651 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4652 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004653 return MakeCXCursor(IFD, getCursorTU(C));
4654
4655 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4656 }
4657
4658 return C;
4659}
4660
4661int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4662 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4663}
4664
4665unsigned clang_getNumOverloadedDecls(CXCursor C) {
4666 if (C.kind != CXCursor_OverloadedDeclRef)
4667 return 0;
4668
4669 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004670 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004671 return E->getNumDecls();
4672
4673 if (OverloadedTemplateStorage *S
4674 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4675 return S->size();
4676
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004677 const Decl *D = Storage.get<const Decl *>();
4678 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004679 return Using->shadow_size();
4680
4681 return 0;
4682}
4683
4684CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4685 if (cursor.kind != CXCursor_OverloadedDeclRef)
4686 return clang_getNullCursor();
4687
4688 if (index >= clang_getNumOverloadedDecls(cursor))
4689 return clang_getNullCursor();
4690
4691 CXTranslationUnit TU = getCursorTU(cursor);
4692 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004693 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004694 return MakeCXCursor(E->decls_begin()[index], TU);
4695
4696 if (OverloadedTemplateStorage *S
4697 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4698 return MakeCXCursor(S->begin()[index], TU);
4699
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004700 const Decl *D = Storage.get<const Decl *>();
4701 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004702 // FIXME: This is, unfortunately, linear time.
4703 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4704 std::advance(Pos, index);
4705 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4706 }
4707
4708 return clang_getNullCursor();
4709}
4710
4711void clang_getDefinitionSpellingAndExtent(CXCursor C,
4712 const char **startBuf,
4713 const char **endBuf,
4714 unsigned *startLine,
4715 unsigned *startColumn,
4716 unsigned *endLine,
4717 unsigned *endColumn) {
4718 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004719 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004720 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4721
4722 SourceManager &SM = FD->getASTContext().getSourceManager();
4723 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4724 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4725 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4726 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4727 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4728 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4729}
4730
4731
4732CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4733 unsigned PieceIndex) {
4734 RefNamePieces Pieces;
4735
4736 switch (C.kind) {
4737 case CXCursor_MemberRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004738 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004739 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4740 E->getQualifierLoc().getSourceRange());
4741 break;
4742
4743 case CXCursor_DeclRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004744 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004745 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4746 E->getQualifierLoc().getSourceRange(),
4747 E->getOptionalExplicitTemplateArgs());
4748 break;
4749
4750 case CXCursor_CallExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004751 if (const CXXOperatorCallExpr *OCE =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004752 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004753 const Expr *Callee = OCE->getCallee();
4754 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004755 Callee = ICE->getSubExpr();
4756
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004757 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004758 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4759 DRE->getQualifierLoc().getSourceRange());
4760 }
4761 break;
4762
4763 default:
4764 break;
4765 }
4766
4767 if (Pieces.empty()) {
4768 if (PieceIndex == 0)
4769 return clang_getCursorExtent(C);
4770 } else if (PieceIndex < Pieces.size()) {
4771 SourceRange R = Pieces[PieceIndex];
4772 if (R.isValid())
4773 return cxloc::translateSourceRange(getCursorContext(C), R);
4774 }
4775
4776 return clang_getNullRange();
4777}
4778
4779void clang_enableStackTraces(void) {
4780 llvm::sys::PrintStackTraceOnErrorSignal();
4781}
4782
4783void clang_executeOnThread(void (*fn)(void*), void *user_data,
4784 unsigned stack_size) {
4785 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4786}
4787
4788} // end: extern "C"
4789
4790//===----------------------------------------------------------------------===//
4791// Token-based Operations.
4792//===----------------------------------------------------------------------===//
4793
4794/* CXToken layout:
4795 * int_data[0]: a CXTokenKind
4796 * int_data[1]: starting token location
4797 * int_data[2]: token length
4798 * int_data[3]: reserved
4799 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4800 * otherwise unused.
4801 */
4802extern "C" {
4803
4804CXTokenKind clang_getTokenKind(CXToken CXTok) {
4805 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4806}
4807
4808CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4809 switch (clang_getTokenKind(CXTok)) {
4810 case CXToken_Identifier:
4811 case CXToken_Keyword:
4812 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00004813 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004814 ->getNameStart());
4815
4816 case CXToken_Literal: {
4817 // We have stashed the starting pointer in the ptr_data field. Use it.
4818 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004819 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004820 }
4821
4822 case CXToken_Punctuation:
4823 case CXToken_Comment:
4824 break;
4825 }
4826
4827 // We have to find the starting buffer pointer the hard way, by
4828 // deconstructing the source location.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004829 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004830 if (!CXXUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004831 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004832
4833 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4834 std::pair<FileID, unsigned> LocInfo
4835 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4836 bool Invalid = false;
4837 StringRef Buffer
4838 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4839 if (Invalid)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004840 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004841
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004842 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004843}
4844
4845CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004846 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004847 if (!CXXUnit)
4848 return clang_getNullLocation();
4849
4850 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4851 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4852}
4853
4854CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004855 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004856 if (!CXXUnit)
4857 return clang_getNullRange();
4858
4859 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4860 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4861}
4862
4863static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4864 SmallVectorImpl<CXToken> &CXTokens) {
4865 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4866 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004867 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004868 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004869 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004870
4871 // Cannot tokenize across files.
4872 if (BeginLocInfo.first != EndLocInfo.first)
4873 return;
4874
4875 // Create a lexer
4876 bool Invalid = false;
4877 StringRef Buffer
4878 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4879 if (Invalid)
4880 return;
4881
4882 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4883 CXXUnit->getASTContext().getLangOpts(),
4884 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4885 Lex.SetCommentRetentionState(true);
4886
4887 // Lex tokens until we hit the end of the range.
4888 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4889 Token Tok;
4890 bool previousWasAt = false;
4891 do {
4892 // Lex the next token
4893 Lex.LexFromRawLexer(Tok);
4894 if (Tok.is(tok::eof))
4895 break;
4896
4897 // Initialize the CXToken.
4898 CXToken CXTok;
4899
4900 // - Common fields
4901 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4902 CXTok.int_data[2] = Tok.getLength();
4903 CXTok.int_data[3] = 0;
4904
4905 // - Kind-specific fields
4906 if (Tok.isLiteral()) {
4907 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00004908 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004909 } else if (Tok.is(tok::raw_identifier)) {
4910 // Lookup the identifier to determine whether we have a keyword.
4911 IdentifierInfo *II
4912 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4913
4914 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4915 CXTok.int_data[0] = CXToken_Keyword;
4916 }
4917 else {
4918 CXTok.int_data[0] = Tok.is(tok::identifier)
4919 ? CXToken_Identifier
4920 : CXToken_Keyword;
4921 }
4922 CXTok.ptr_data = II;
4923 } else if (Tok.is(tok::comment)) {
4924 CXTok.int_data[0] = CXToken_Comment;
4925 CXTok.ptr_data = 0;
4926 } else {
4927 CXTok.int_data[0] = CXToken_Punctuation;
4928 CXTok.ptr_data = 0;
4929 }
4930 CXTokens.push_back(CXTok);
4931 previousWasAt = Tok.is(tok::at);
4932 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
4933}
4934
4935void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4936 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00004937 LOG_FUNC_SECTION {
4938 *Log << TU << ' ' << Range;
4939 }
4940
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004941 if (Tokens)
4942 *Tokens = 0;
4943 if (NumTokens)
4944 *NumTokens = 0;
4945
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00004946 if (!TU)
4947 return;
4948
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004949 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004950 if (!CXXUnit || !Tokens || !NumTokens)
4951 return;
4952
4953 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4954
4955 SourceRange R = cxloc::translateCXSourceRange(Range);
4956 if (R.isInvalid())
4957 return;
4958
4959 SmallVector<CXToken, 32> CXTokens;
4960 getTokens(CXXUnit, R, CXTokens);
4961
4962 if (CXTokens.empty())
4963 return;
4964
4965 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4966 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4967 *NumTokens = CXTokens.size();
4968}
4969
4970void clang_disposeTokens(CXTranslationUnit TU,
4971 CXToken *Tokens, unsigned NumTokens) {
4972 free(Tokens);
4973}
4974
4975} // end: extern "C"
4976
4977//===----------------------------------------------------------------------===//
4978// Token annotation APIs.
4979//===----------------------------------------------------------------------===//
4980
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004981static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4982 CXCursor parent,
4983 CXClientData client_data);
4984static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
4985 CXClientData client_data);
4986
4987namespace {
4988class AnnotateTokensWorker {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004989 CXToken *Tokens;
4990 CXCursor *Cursors;
4991 unsigned NumTokens;
4992 unsigned TokIdx;
4993 unsigned PreprocessingTokIdx;
4994 CursorVisitor AnnotateVis;
4995 SourceManager &SrcMgr;
4996 bool HasContextSensitiveKeywords;
4997
4998 struct PostChildrenInfo {
4999 CXCursor Cursor;
5000 SourceRange CursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005001 unsigned BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005002 unsigned BeforeChildrenTokenIdx;
5003 };
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00005004 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005005
5006 bool MoreTokens() const { return TokIdx < NumTokens; }
5007 unsigned NextToken() const { return TokIdx; }
5008 void AdvanceToken() { ++TokIdx; }
5009 SourceLocation GetTokenLoc(unsigned tokI) {
5010 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5011 }
5012 bool isFunctionMacroToken(unsigned tokI) const {
5013 return Tokens[tokI].int_data[3] != 0;
5014 }
5015 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
5016 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
5017 }
5018
5019 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005020 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005021 SourceRange);
5022
5023public:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005024 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005025 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005026 : Tokens(tokens), Cursors(cursors),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005027 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005028 AnnotateVis(TU,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005029 AnnotateTokensVisitor, this,
5030 /*VisitPreprocessorLast=*/true,
5031 /*VisitIncludedEntities=*/false,
5032 RegionOfInterest,
5033 /*VisitDeclsOnly=*/false,
5034 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005035 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005036 HasContextSensitiveKeywords(false) { }
5037
5038 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5039 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5040 bool postVisitChildren(CXCursor cursor);
5041 void AnnotateTokens();
5042
5043 /// \brief Determine whether the annotator saw any cursors that have
5044 /// context-sensitive keywords.
5045 bool hasContextSensitiveKeywords() const {
5046 return HasContextSensitiveKeywords;
5047 }
5048
5049 ~AnnotateTokensWorker() {
5050 assert(PostChildrenInfos.empty());
5051 }
5052};
5053}
5054
5055void AnnotateTokensWorker::AnnotateTokens() {
5056 // Walk the AST within the region of interest, annotating tokens
5057 // along the way.
5058 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005059}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005060
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005061static inline void updateCursorAnnotation(CXCursor &Cursor,
5062 const CXCursor &updateC) {
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005063 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005064 return;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005065 Cursor = updateC;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005066}
5067
5068/// \brief It annotates and advances tokens with a cursor until the comparison
5069//// between the cursor location and the source range is the same as
5070/// \arg compResult.
5071///
5072/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5073/// Pass RangeOverlap to annotate tokens inside a range.
5074void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5075 RangeComparisonResult compResult,
5076 SourceRange range) {
5077 while (MoreTokens()) {
5078 const unsigned I = NextToken();
5079 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005080 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5081 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005082
5083 SourceLocation TokLoc = GetTokenLoc(I);
5084 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005085 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005086 AdvanceToken();
5087 continue;
5088 }
5089 break;
5090 }
5091}
5092
5093/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005094/// \returns true if it advanced beyond all macro tokens, false otherwise.
5095bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005096 CXCursor updateC,
5097 RangeComparisonResult compResult,
5098 SourceRange range) {
5099 assert(MoreTokens());
5100 assert(isFunctionMacroToken(NextToken()) &&
5101 "Should be called only for macro arg tokens");
5102
5103 // This works differently than annotateAndAdvanceTokens; because expanded
5104 // macro arguments can have arbitrary translation-unit source order, we do not
5105 // advance the token index one by one until a token fails the range test.
5106 // We only advance once past all of the macro arg tokens if all of them
5107 // pass the range test. If one of them fails we keep the token index pointing
5108 // at the start of the macro arg tokens so that the failing token will be
5109 // annotated by a subsequent annotation try.
5110
5111 bool atLeastOneCompFail = false;
5112
5113 unsigned I = NextToken();
5114 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5115 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5116 if (TokLoc.isFileID())
5117 continue; // not macro arg token, it's parens or comma.
5118 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5119 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5120 Cursors[I] = updateC;
5121 } else
5122 atLeastOneCompFail = true;
5123 }
5124
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005125 if (atLeastOneCompFail)
5126 return false;
5127
5128 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5129 return true;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005130}
5131
5132enum CXChildVisitResult
5133AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005134 SourceRange cursorRange = getRawCursorExtent(cursor);
5135 if (cursorRange.isInvalid())
5136 return CXChildVisit_Recurse;
5137
5138 if (!HasContextSensitiveKeywords) {
5139 // Objective-C properties can have context-sensitive keywords.
5140 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005141 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005142 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5143 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5144 }
5145 // Objective-C methods can have context-sensitive keywords.
5146 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5147 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005148 if (const ObjCMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005149 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5150 if (Method->getObjCDeclQualifier())
5151 HasContextSensitiveKeywords = true;
5152 else {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005153 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5154 PEnd = Method->param_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005155 P != PEnd; ++P) {
5156 if ((*P)->getObjCDeclQualifier()) {
5157 HasContextSensitiveKeywords = true;
5158 break;
5159 }
5160 }
5161 }
5162 }
5163 }
5164 // C++ methods can have context-sensitive keywords.
5165 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005166 if (const CXXMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005167 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5168 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5169 HasContextSensitiveKeywords = true;
5170 }
5171 }
5172 // C++ classes can have context-sensitive keywords.
5173 else if (cursor.kind == CXCursor_StructDecl ||
5174 cursor.kind == CXCursor_ClassDecl ||
5175 cursor.kind == CXCursor_ClassTemplate ||
5176 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005177 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005178 if (D->hasAttr<FinalAttr>())
5179 HasContextSensitiveKeywords = true;
5180 }
5181 }
5182
5183 if (clang_isPreprocessing(cursor.kind)) {
5184 // Items in the preprocessing record are kept separate from items in
5185 // declarations, so we keep a separate token index.
5186 unsigned SavedTokIdx = TokIdx;
5187 TokIdx = PreprocessingTokIdx;
5188
5189 // Skip tokens up until we catch up to the beginning of the preprocessing
5190 // entry.
5191 while (MoreTokens()) {
5192 const unsigned I = NextToken();
5193 SourceLocation TokLoc = GetTokenLoc(I);
5194 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5195 case RangeBefore:
5196 AdvanceToken();
5197 continue;
5198 case RangeAfter:
5199 case RangeOverlap:
5200 break;
5201 }
5202 break;
5203 }
5204
5205 // Look at all of the tokens within this range.
5206 while (MoreTokens()) {
5207 const unsigned I = NextToken();
5208 SourceLocation TokLoc = GetTokenLoc(I);
5209 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5210 case RangeBefore:
5211 llvm_unreachable("Infeasible");
5212 case RangeAfter:
5213 break;
5214 case RangeOverlap:
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005215 // For macro expansions, just note where the beginning of the macro
5216 // expansion occurs.
5217 if (cursor.kind == CXCursor_MacroExpansion) {
5218 if (TokLoc == cursorRange.getBegin())
5219 Cursors[I] = cursor;
5220 AdvanceToken();
5221 break;
5222 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005223 // We may have already annotated macro names inside macro definitions.
5224 if (Cursors[I].kind != CXCursor_MacroExpansion)
5225 Cursors[I] = cursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005226 AdvanceToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005227 continue;
5228 }
5229 break;
5230 }
5231
5232 // Save the preprocessing token index; restore the non-preprocessing
5233 // token index.
5234 PreprocessingTokIdx = TokIdx;
5235 TokIdx = SavedTokIdx;
5236 return CXChildVisit_Recurse;
5237 }
5238
5239 if (cursorRange.isInvalid())
5240 return CXChildVisit_Continue;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005241
5242 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005243 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005244 const enum CXCursorKind K = clang_getCursorKind(parent);
5245 const CXCursor updateC =
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005246 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5247 // Attributes are annotated out-of-order, skip tokens until we reach it.
5248 clang_isAttribute(cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005249 ? clang_getNullCursor() : parent;
5250
5251 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5252
5253 // Avoid having the cursor of an expression "overwrite" the annotation of the
5254 // variable declaration that it belongs to.
5255 // This can happen for C++ constructor expressions whose range generally
5256 // include the variable declaration, e.g.:
5257 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5258 if (clang_isExpression(cursorK)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00005259 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenko404628c2013-01-26 18:12:08 +00005260 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005261 const unsigned I = NextToken();
5262 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5263 E->getLocStart() == D->getLocation() &&
5264 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005265 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005266 AdvanceToken();
5267 }
5268 }
5269 }
5270
5271 // Before recursing into the children keep some state that we are going
5272 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5273 // extra work after the child nodes are visited.
5274 // Note that we don't call VisitChildren here to avoid traversing statements
5275 // code-recursively which can blow the stack.
5276
5277 PostChildrenInfo Info;
5278 Info.Cursor = cursor;
5279 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005280 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005281 Info.BeforeChildrenTokenIdx = NextToken();
5282 PostChildrenInfos.push_back(Info);
5283
5284 return CXChildVisit_Recurse;
5285}
5286
5287bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5288 if (PostChildrenInfos.empty())
5289 return false;
5290 const PostChildrenInfo &Info = PostChildrenInfos.back();
5291 if (!clang_equalCursors(Info.Cursor, cursor))
5292 return false;
5293
5294 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5295 const unsigned AfterChildren = NextToken();
5296 SourceRange cursorRange = Info.CursorRange;
5297
5298 // Scan the tokens that are at the end of the cursor, but are not captured
5299 // but the child cursors.
5300 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5301
5302 // Scan the tokens that are at the beginning of the cursor, but are not
5303 // capture by the child cursors.
5304 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5305 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5306 break;
5307
5308 Cursors[I] = cursor;
5309 }
5310
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005311 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5312 // encountered the attribute cursor.
5313 if (clang_isAttribute(cursor.kind))
5314 TokIdx = Info.BeforeReachingCursorIdx;
5315
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005316 PostChildrenInfos.pop_back();
5317 return false;
5318}
5319
5320static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5321 CXCursor parent,
5322 CXClientData client_data) {
5323 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5324}
5325
5326static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5327 CXClientData client_data) {
5328 return static_cast<AnnotateTokensWorker*>(client_data)->
5329 postVisitChildren(cursor);
5330}
5331
5332namespace {
5333
5334/// \brief Uses the macro expansions in the preprocessing record to find
5335/// and mark tokens that are macro arguments. This info is used by the
5336/// AnnotateTokensWorker.
5337class MarkMacroArgTokensVisitor {
5338 SourceManager &SM;
5339 CXToken *Tokens;
5340 unsigned NumTokens;
5341 unsigned CurIdx;
5342
5343public:
5344 MarkMacroArgTokensVisitor(SourceManager &SM,
5345 CXToken *tokens, unsigned numTokens)
5346 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5347
5348 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5349 if (cursor.kind != CXCursor_MacroExpansion)
5350 return CXChildVisit_Continue;
5351
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00005352 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005353 if (macroRange.getBegin() == macroRange.getEnd())
5354 return CXChildVisit_Continue; // it's not a function macro.
5355
5356 for (; CurIdx < NumTokens; ++CurIdx) {
5357 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5358 macroRange.getBegin()))
5359 break;
5360 }
5361
5362 if (CurIdx == NumTokens)
5363 return CXChildVisit_Break;
5364
5365 for (; CurIdx < NumTokens; ++CurIdx) {
5366 SourceLocation tokLoc = getTokenLoc(CurIdx);
5367 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5368 break;
5369
5370 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5371 }
5372
5373 if (CurIdx == NumTokens)
5374 return CXChildVisit_Break;
5375
5376 return CXChildVisit_Continue;
5377 }
5378
5379private:
5380 SourceLocation getTokenLoc(unsigned tokI) {
5381 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5382 }
5383
5384 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5385 // The third field is reserved and currently not used. Use it here
5386 // to mark macro arg expanded tokens with their expanded locations.
5387 Tokens[tokI].int_data[3] = loc.getRawEncoding();
5388 }
5389};
5390
5391} // end anonymous namespace
5392
5393static CXChildVisitResult
5394MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5395 CXClientData client_data) {
5396 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5397 parent);
5398}
5399
5400namespace {
5401 struct clang_annotateTokens_Data {
5402 CXTranslationUnit TU;
5403 ASTUnit *CXXUnit;
5404 CXToken *Tokens;
5405 unsigned NumTokens;
5406 CXCursor *Cursors;
5407 };
5408}
5409
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005410/// \brief Used by \c annotatePreprocessorTokens.
5411/// \returns true if lexing was finished, false otherwise.
5412static bool lexNext(Lexer &Lex, Token &Tok,
5413 unsigned &NextIdx, unsigned NumTokens) {
5414 if (NextIdx >= NumTokens)
5415 return true;
5416
5417 ++NextIdx;
5418 Lex.LexFromRawLexer(Tok);
5419 if (Tok.is(tok::eof))
5420 return true;
5421
5422 return false;
5423}
5424
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005425static void annotatePreprocessorTokens(CXTranslationUnit TU,
5426 SourceRange RegionOfInterest,
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005427 CXCursor *Cursors,
5428 CXToken *Tokens,
5429 unsigned NumTokens) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005430 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005431
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005432 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005433 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5434 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005435 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005436 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005437 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005438
5439 if (BeginLocInfo.first != EndLocInfo.first)
5440 return;
5441
5442 StringRef Buffer;
5443 bool Invalid = false;
5444 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5445 if (Buffer.empty() || Invalid)
5446 return;
5447
5448 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5449 CXXUnit->getASTContext().getLangOpts(),
5450 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5451 Buffer.end());
5452 Lex.SetCommentRetentionState(true);
5453
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005454 unsigned NextIdx = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005455 // Lex tokens in raw mode until we hit the end of the range, to avoid
5456 // entering #includes or expanding macros.
5457 while (true) {
5458 Token Tok;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005459 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5460 break;
5461 unsigned TokIdx = NextIdx-1;
5462 assert(Tok.getLocation() ==
5463 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005464
5465 reprocess:
5466 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005467 // We have found a preprocessing directive. Annotate the tokens
5468 // appropriately.
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005469 //
5470 // FIXME: Some simple tests here could identify macro definitions and
5471 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005472
5473 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005474 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5475 break;
5476
5477 MacroInfo *MI = 0;
5478 if (Tok.is(tok::raw_identifier) &&
5479 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5480 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5481 break;
5482
5483 if (Tok.is(tok::raw_identifier)) {
5484 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5485 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5486 SourceLocation MappedTokLoc =
5487 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5488 MI = getMacroInfo(II, MappedTokLoc, TU);
5489 }
5490 }
5491
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005492 bool finished = false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005493 do {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005494 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5495 finished = true;
5496 break;
5497 }
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005498 // If we are in a macro definition, check if the token was ever a
5499 // macro name and annotate it if that's the case.
5500 if (MI) {
5501 SourceLocation SaveLoc = Tok.getLocation();
5502 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5503 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5504 Tok.setLocation(SaveLoc);
5505 if (MacroDef)
5506 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5507 Tok.getLocation(), TU);
5508 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005509 } while (!Tok.isAtStartOfLine());
5510
5511 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5512 assert(TokIdx <= LastIdx);
5513 SourceLocation EndLoc =
5514 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5515 CXCursor Cursor =
5516 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5517
5518 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005519 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005520
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005521 if (finished)
5522 break;
5523 goto reprocess;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005524 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005525 }
5526}
5527
5528// This gets run a separate thread to avoid stack blowout.
5529static void clang_annotateTokensImpl(void *UserData) {
5530 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5531 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5532 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5533 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5534 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5535
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00005536 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005537 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5538 setThreadBackgroundPriority();
5539
5540 // Determine the region of interest, which contains all of the tokens.
5541 SourceRange RegionOfInterest;
5542 RegionOfInterest.setBegin(
5543 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5544 RegionOfInterest.setEnd(
5545 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5546 Tokens[NumTokens-1])));
5547
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005548 // Relex the tokens within the source range to look for preprocessing
5549 // directives.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005550 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005551
5552 // If begin location points inside a macro argument, set it to the expansion
5553 // location so we can have the full context when annotating semantically.
5554 {
5555 SourceManager &SM = CXXUnit->getSourceManager();
5556 SourceLocation Loc =
5557 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5558 if (Loc.isMacroID())
5559 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5560 }
5561
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005562 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5563 // Search and mark tokens that are macro argument expansions.
5564 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5565 Tokens, NumTokens);
5566 CursorVisitor MacroArgMarker(TU,
5567 MarkMacroArgTokensVisitorDelegate, &Visitor,
5568 /*VisitPreprocessorLast=*/true,
5569 /*VisitIncludedEntities=*/false,
5570 RegionOfInterest);
5571 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5572 }
5573
5574 // Annotate all of the source locations in the region of interest that map to
5575 // a specific cursor.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005576 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005577
5578 // FIXME: We use a ridiculous stack size here because the data-recursion
5579 // algorithm uses a large stack frame than the non-data recursive version,
5580 // and AnnotationTokensWorker currently transforms the data-recursion
5581 // algorithm back into a traditional recursion by explicitly calling
5582 // VisitChildren(). We will need to remove this explicit recursive call.
5583 W.AnnotateTokens();
5584
5585 // If we ran into any entities that involve context-sensitive keywords,
5586 // take another pass through the tokens to mark them as such.
5587 if (W.hasContextSensitiveKeywords()) {
5588 for (unsigned I = 0; I != NumTokens; ++I) {
5589 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5590 continue;
5591
5592 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5593 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005594 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005595 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5596 if (Property->getPropertyAttributesAsWritten() != 0 &&
5597 llvm::StringSwitch<bool>(II->getName())
5598 .Case("readonly", true)
5599 .Case("assign", true)
5600 .Case("unsafe_unretained", true)
5601 .Case("readwrite", true)
5602 .Case("retain", true)
5603 .Case("copy", true)
5604 .Case("nonatomic", true)
5605 .Case("atomic", true)
5606 .Case("getter", true)
5607 .Case("setter", true)
5608 .Case("strong", true)
5609 .Case("weak", true)
5610 .Default(false))
5611 Tokens[I].int_data[0] = CXToken_Keyword;
5612 }
5613 continue;
5614 }
5615
5616 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5617 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5618 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5619 if (llvm::StringSwitch<bool>(II->getName())
5620 .Case("in", true)
5621 .Case("out", true)
5622 .Case("inout", true)
5623 .Case("oneway", true)
5624 .Case("bycopy", true)
5625 .Case("byref", true)
5626 .Default(false))
5627 Tokens[I].int_data[0] = CXToken_Keyword;
5628 continue;
5629 }
5630
5631 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5632 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5633 Tokens[I].int_data[0] = CXToken_Keyword;
5634 continue;
5635 }
5636 }
5637 }
5638}
5639
5640extern "C" {
5641
5642void clang_annotateTokens(CXTranslationUnit TU,
5643 CXToken *Tokens, unsigned NumTokens,
5644 CXCursor *Cursors) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00005645 if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005646 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005647 return;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005648 }
5649
5650 LOG_FUNC_SECTION {
5651 *Log << TU << ' ';
5652 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5653 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5654 *Log << clang_getRange(bloc, eloc);
5655 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005656
5657 // Any token we don't specifically annotate will have a NULL cursor.
5658 CXCursor C = clang_getNullCursor();
5659 for (unsigned I = 0; I != NumTokens; ++I)
5660 Cursors[I] = C;
5661
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005662 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005663 if (!CXXUnit)
5664 return;
5665
5666 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5667
5668 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5669 llvm::CrashRecoveryContext CRC;
5670 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5671 GetSafetyThreadStackSize() * 2)) {
5672 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5673 }
5674}
5675
5676} // end: extern "C"
5677
5678//===----------------------------------------------------------------------===//
5679// Operations for querying linkage of a cursor.
5680//===----------------------------------------------------------------------===//
5681
5682extern "C" {
5683CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5684 if (!clang_isDeclaration(cursor.kind))
5685 return CXLinkage_Invalid;
5686
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005687 const Decl *D = cxcursor::getCursorDecl(cursor);
5688 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola181e3ec2013-05-13 00:12:11 +00005689 switch (ND->getLinkageInternal()) {
Rafael Espindolaa99ecbc2013-05-25 17:16:20 +00005690 case NoLinkage:
5691 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005692 case InternalLinkage: return CXLinkage_Internal;
5693 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5694 case ExternalLinkage: return CXLinkage_External;
5695 };
5696
5697 return CXLinkage_Invalid;
5698}
5699} // end: extern "C"
5700
5701//===----------------------------------------------------------------------===//
5702// Operations for querying language of a cursor.
5703//===----------------------------------------------------------------------===//
5704
5705static CXLanguageKind getDeclLanguage(const Decl *D) {
5706 if (!D)
5707 return CXLanguage_C;
5708
5709 switch (D->getKind()) {
5710 default:
5711 break;
5712 case Decl::ImplicitParam:
5713 case Decl::ObjCAtDefsField:
5714 case Decl::ObjCCategory:
5715 case Decl::ObjCCategoryImpl:
5716 case Decl::ObjCCompatibleAlias:
5717 case Decl::ObjCImplementation:
5718 case Decl::ObjCInterface:
5719 case Decl::ObjCIvar:
5720 case Decl::ObjCMethod:
5721 case Decl::ObjCProperty:
5722 case Decl::ObjCPropertyImpl:
5723 case Decl::ObjCProtocol:
5724 return CXLanguage_ObjC;
5725 case Decl::CXXConstructor:
5726 case Decl::CXXConversion:
5727 case Decl::CXXDestructor:
5728 case Decl::CXXMethod:
5729 case Decl::CXXRecord:
5730 case Decl::ClassTemplate:
5731 case Decl::ClassTemplatePartialSpecialization:
5732 case Decl::ClassTemplateSpecialization:
5733 case Decl::Friend:
5734 case Decl::FriendTemplate:
5735 case Decl::FunctionTemplate:
5736 case Decl::LinkageSpec:
5737 case Decl::Namespace:
5738 case Decl::NamespaceAlias:
5739 case Decl::NonTypeTemplateParm:
5740 case Decl::StaticAssert:
5741 case Decl::TemplateTemplateParm:
5742 case Decl::TemplateTypeParm:
5743 case Decl::UnresolvedUsingTypename:
5744 case Decl::UnresolvedUsingValue:
5745 case Decl::Using:
5746 case Decl::UsingDirective:
5747 case Decl::UsingShadow:
5748 return CXLanguage_CPlusPlus;
5749 }
5750
5751 return CXLanguage_C;
5752}
5753
5754extern "C" {
5755
5756enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5757 if (clang_isDeclaration(cursor.kind))
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005758 if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005759 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5760 return CXAvailability_Available;
5761
5762 switch (D->getAvailability()) {
5763 case AR_Available:
5764 case AR_NotYetIntroduced:
5765 return CXAvailability_Available;
5766
5767 case AR_Deprecated:
5768 return CXAvailability_Deprecated;
5769
5770 case AR_Unavailable:
5771 return CXAvailability_NotAvailable;
5772 }
5773 }
5774
5775 return CXAvailability_Available;
5776}
5777
5778static CXVersion convertVersion(VersionTuple In) {
5779 CXVersion Out = { -1, -1, -1 };
5780 if (In.empty())
5781 return Out;
5782
5783 Out.Major = In.getMajor();
5784
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005785 Optional<unsigned> Minor = In.getMinor();
5786 if (Minor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005787 Out.Minor = *Minor;
5788 else
5789 return Out;
5790
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005791 Optional<unsigned> Subminor = In.getSubminor();
5792 if (Subminor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005793 Out.Subminor = *Subminor;
5794
5795 return Out;
5796}
5797
5798int clang_getCursorPlatformAvailability(CXCursor cursor,
5799 int *always_deprecated,
5800 CXString *deprecated_message,
5801 int *always_unavailable,
5802 CXString *unavailable_message,
5803 CXPlatformAvailability *availability,
5804 int availability_size) {
5805 if (always_deprecated)
5806 *always_deprecated = 0;
5807 if (deprecated_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005808 *deprecated_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005809 if (always_unavailable)
5810 *always_unavailable = 0;
5811 if (unavailable_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005812 *unavailable_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005813
5814 if (!clang_isDeclaration(cursor.kind))
5815 return 0;
5816
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005817 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005818 if (!D)
5819 return 0;
5820
5821 int N = 0;
5822 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5823 ++A) {
5824 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5825 if (always_deprecated)
5826 *always_deprecated = 1;
5827 if (deprecated_message)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005828 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005829 continue;
5830 }
5831
5832 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5833 if (always_unavailable)
5834 *always_unavailable = 1;
5835 if (unavailable_message) {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005836 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005837 }
5838 continue;
5839 }
5840
5841 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5842 if (N < availability_size) {
5843 availability[N].Platform
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005844 = cxstring::createDup(Avail->getPlatform()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005845 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5846 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5847 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5848 availability[N].Unavailable = Avail->getUnavailable();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005849 availability[N].Message = cxstring::createDup(Avail->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005850 }
5851 ++N;
5852 }
5853 }
5854
5855 return N;
5856}
5857
5858void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5859 clang_disposeString(availability->Platform);
5860 clang_disposeString(availability->Message);
5861}
5862
5863CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5864 if (clang_isDeclaration(cursor.kind))
5865 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5866
5867 return CXLanguage_Invalid;
5868}
5869
5870 /// \brief If the given cursor is the "templated" declaration
5871 /// descibing a class or function template, return the class or
5872 /// function template.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005873static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005874 if (!D)
5875 return 0;
5876
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005877 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005878 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
5879 return FunTmpl;
5880
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005881 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005882 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
5883 return ClassTmpl;
5884
5885 return D;
5886}
5887
5888CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
5889 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005890 if (const Decl *D = getCursorDecl(cursor)) {
5891 const DeclContext *DC = D->getDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005892 if (!DC)
5893 return clang_getNullCursor();
5894
5895 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5896 getCursorTU(cursor));
5897 }
5898 }
5899
5900 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005901 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005902 return MakeCXCursor(D, getCursorTU(cursor));
5903 }
5904
5905 return clang_getNullCursor();
5906}
5907
5908CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5909 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005910 if (const Decl *D = getCursorDecl(cursor)) {
5911 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005912 if (!DC)
5913 return clang_getNullCursor();
5914
5915 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5916 getCursorTU(cursor));
5917 }
5918 }
5919
5920 // FIXME: Note that we can't easily compute the lexical context of a
5921 // statement or expression, so we return nothing.
5922 return clang_getNullCursor();
5923}
5924
5925CXFile clang_getIncludedFile(CXCursor cursor) {
5926 if (cursor.kind != CXCursor_InclusionDirective)
5927 return 0;
5928
Dmitri Gribenko67812b22013-01-11 21:01:49 +00005929 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00005930 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005931}
5932
Argyrios Kyrtzidis9ee6a662013-04-18 22:15:49 +00005933unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
5934 if (C.kind != CXCursor_ObjCPropertyDecl)
5935 return CXObjCPropertyAttr_noattr;
5936
5937 unsigned Result = CXObjCPropertyAttr_noattr;
5938 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
5939 ObjCPropertyDecl::PropertyAttributeKind Attr =
5940 PD->getPropertyAttributesAsWritten();
5941
5942#define SET_CXOBJCPROP_ATTR(A) \
5943 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
5944 Result |= CXObjCPropertyAttr_##A
5945 SET_CXOBJCPROP_ATTR(readonly);
5946 SET_CXOBJCPROP_ATTR(getter);
5947 SET_CXOBJCPROP_ATTR(assign);
5948 SET_CXOBJCPROP_ATTR(readwrite);
5949 SET_CXOBJCPROP_ATTR(retain);
5950 SET_CXOBJCPROP_ATTR(copy);
5951 SET_CXOBJCPROP_ATTR(nonatomic);
5952 SET_CXOBJCPROP_ATTR(setter);
5953 SET_CXOBJCPROP_ATTR(atomic);
5954 SET_CXOBJCPROP_ATTR(weak);
5955 SET_CXOBJCPROP_ATTR(strong);
5956 SET_CXOBJCPROP_ATTR(unsafe_unretained);
5957#undef SET_CXOBJCPROP_ATTR
5958
5959 return Result;
5960}
5961
Argyrios Kyrtzidis38dbad22013-04-18 23:29:12 +00005962unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
5963 if (!clang_isDeclaration(C.kind))
5964 return CXObjCDeclQualifier_None;
5965
5966 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
5967 const Decl *D = getCursorDecl(C);
5968 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
5969 QT = MD->getObjCDeclQualifier();
5970 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
5971 QT = PD->getObjCDeclQualifier();
5972 if (QT == Decl::OBJC_TQ_None)
5973 return CXObjCDeclQualifier_None;
5974
5975 unsigned Result = CXObjCDeclQualifier_None;
5976 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
5977 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
5978 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
5979 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
5980 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
5981 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
5982
5983 return Result;
5984}
5985
Argyrios Kyrtzidis80e1aca2013-04-18 23:53:05 +00005986unsigned clang_Cursor_isVariadic(CXCursor C) {
5987 if (!clang_isDeclaration(C.kind))
5988 return 0;
5989
5990 const Decl *D = getCursorDecl(C);
5991 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
5992 return FD->isVariadic();
5993 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
5994 return MD->isVariadic();
5995
5996 return 0;
5997}
5998
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005999CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6000 if (!clang_isDeclaration(C.kind))
6001 return clang_getNullRange();
6002
6003 const Decl *D = getCursorDecl(C);
6004 ASTContext &Context = getCursorContext(C);
6005 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6006 if (!RC)
6007 return clang_getNullRange();
6008
6009 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6010}
6011
6012CXString clang_Cursor_getRawCommentText(CXCursor C) {
6013 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006014 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006015
6016 const Decl *D = getCursorDecl(C);
6017 ASTContext &Context = getCursorContext(C);
6018 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6019 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6020 StringRef();
6021
6022 // Don't duplicate the string because RawText points directly into source
6023 // code.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006024 return cxstring::createRef(RawText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006025}
6026
6027CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6028 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006029 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006030
6031 const Decl *D = getCursorDecl(C);
6032 const ASTContext &Context = getCursorContext(C);
6033 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6034
6035 if (RC) {
6036 StringRef BriefText = RC->getBriefText(Context);
6037
6038 // Don't duplicate the string because RawComment ensures that this memory
6039 // will not go away.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006040 return cxstring::createRef(BriefText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006041 }
6042
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006043 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006044}
6045
6046CXComment clang_Cursor_getParsedComment(CXCursor C) {
6047 if (!clang_isDeclaration(C.kind))
6048 return cxcomment::createCXComment(NULL, NULL);
6049
6050 const Decl *D = getCursorDecl(C);
6051 const ASTContext &Context = getCursorContext(C);
6052 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6053
6054 return cxcomment::createCXComment(FC, getCursorTU(C));
6055}
6056
6057CXModule clang_Cursor_getModule(CXCursor C) {
6058 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006059 if (const ImportDecl *ImportD =
6060 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006061 return ImportD->getImportedModule();
6062 }
6063
6064 return 0;
6065}
6066
Argyrios Kyrtzidise858e662013-04-26 22:47:49 +00006067CXFile clang_Module_getASTFile(CXModule CXMod) {
6068 if (!CXMod)
6069 return 0;
6070 Module *Mod = static_cast<Module*>(CXMod);
6071 return const_cast<FileEntry *>(Mod->getASTFile());
6072}
6073
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006074CXModule clang_Module_getParent(CXModule CXMod) {
6075 if (!CXMod)
6076 return 0;
6077 Module *Mod = static_cast<Module*>(CXMod);
6078 return Mod->Parent;
6079}
6080
6081CXString clang_Module_getName(CXModule CXMod) {
6082 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006083 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006084 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006085 return cxstring::createDup(Mod->Name);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006086}
6087
6088CXString clang_Module_getFullName(CXModule CXMod) {
6089 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006090 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006091 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006092 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006093}
6094
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006095unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6096 CXModule CXMod) {
6097 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006098 return 0;
6099 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006100 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6101 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6102 return TopHeaders.size();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006103}
6104
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006105CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6106 CXModule CXMod, unsigned Index) {
6107 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006108 return 0;
6109 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006110 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006111
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006112 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6113 if (Index < TopHeaders.size())
6114 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006115
6116 return 0;
6117}
6118
6119} // end: extern "C"
6120
6121//===----------------------------------------------------------------------===//
6122// C++ AST instrospection.
6123//===----------------------------------------------------------------------===//
6124
6125extern "C" {
Dmitri Gribenkoc965f762013-05-17 18:38:35 +00006126unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6127 if (!clang_isDeclaration(C.kind))
6128 return 0;
6129
6130 const CXXMethodDecl *Method = 0;
6131 const Decl *D = cxcursor::getCursorDecl(C);
6132 if (const FunctionTemplateDecl *FunTmpl =
6133 dyn_cast_or_null<FunctionTemplateDecl>(D))
6134 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6135 else
6136 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6137 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6138}
6139
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006140unsigned clang_CXXMethod_isStatic(CXCursor C) {
6141 if (!clang_isDeclaration(C.kind))
6142 return 0;
6143
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006144 const CXXMethodDecl *Method = 0;
6145 const Decl *D = cxcursor::getCursorDecl(C);
6146 if (const FunctionTemplateDecl *FunTmpl =
6147 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006148 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6149 else
6150 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6151 return (Method && Method->isStatic()) ? 1 : 0;
6152}
6153
6154unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6155 if (!clang_isDeclaration(C.kind))
6156 return 0;
6157
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006158 const CXXMethodDecl *Method = 0;
6159 const Decl *D = cxcursor::getCursorDecl(C);
6160 if (const FunctionTemplateDecl *FunTmpl =
6161 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006162 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6163 else
6164 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6165 return (Method && Method->isVirtual()) ? 1 : 0;
6166}
6167} // end: extern "C"
6168
6169//===----------------------------------------------------------------------===//
6170// Attribute introspection.
6171//===----------------------------------------------------------------------===//
6172
6173extern "C" {
6174CXType clang_getIBOutletCollectionType(CXCursor C) {
6175 if (C.kind != CXCursor_IBOutletCollectionAttr)
6176 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6177
Dmitri Gribenko7d914382013-01-26 18:08:08 +00006178 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006179 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6180
6181 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6182}
6183} // end: extern "C"
6184
6185//===----------------------------------------------------------------------===//
6186// Inspecting memory usage.
6187//===----------------------------------------------------------------------===//
6188
6189typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6190
6191static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6192 enum CXTUResourceUsageKind k,
6193 unsigned long amount) {
6194 CXTUResourceUsageEntry entry = { k, amount };
6195 entries.push_back(entry);
6196}
6197
6198extern "C" {
6199
6200const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6201 const char *str = "";
6202 switch (kind) {
6203 case CXTUResourceUsage_AST:
6204 str = "ASTContext: expressions, declarations, and types";
6205 break;
6206 case CXTUResourceUsage_Identifiers:
6207 str = "ASTContext: identifiers";
6208 break;
6209 case CXTUResourceUsage_Selectors:
6210 str = "ASTContext: selectors";
6211 break;
6212 case CXTUResourceUsage_GlobalCompletionResults:
6213 str = "Code completion: cached global results";
6214 break;
6215 case CXTUResourceUsage_SourceManagerContentCache:
6216 str = "SourceManager: content cache allocator";
6217 break;
6218 case CXTUResourceUsage_AST_SideTables:
6219 str = "ASTContext: side tables";
6220 break;
6221 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6222 str = "SourceManager: malloc'ed memory buffers";
6223 break;
6224 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6225 str = "SourceManager: mmap'ed memory buffers";
6226 break;
6227 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6228 str = "ExternalASTSource: malloc'ed memory buffers";
6229 break;
6230 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6231 str = "ExternalASTSource: mmap'ed memory buffers";
6232 break;
6233 case CXTUResourceUsage_Preprocessor:
6234 str = "Preprocessor: malloc'ed memory";
6235 break;
6236 case CXTUResourceUsage_PreprocessingRecord:
6237 str = "Preprocessor: PreprocessingRecord";
6238 break;
6239 case CXTUResourceUsage_SourceManager_DataStructures:
6240 str = "SourceManager: data structures and tables";
6241 break;
6242 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6243 str = "Preprocessor: header search tables";
6244 break;
6245 }
6246 return str;
6247}
6248
6249CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6250 if (!TU) {
6251 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6252 return usage;
6253 }
6254
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006255 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006256 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6257 ASTContext &astContext = astUnit->getASTContext();
6258
6259 // How much memory is used by AST nodes and types?
6260 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6261 (unsigned long) astContext.getASTAllocatedMemory());
6262
6263 // How much memory is used by identifiers?
6264 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6265 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6266
6267 // How much memory is used for selectors?
6268 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6269 (unsigned long) astContext.Selectors.getTotalMemory());
6270
6271 // How much memory is used by ASTContext's side tables?
6272 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6273 (unsigned long) astContext.getSideTableAllocatedMemory());
6274
6275 // How much memory is used for caching global code completion results?
6276 unsigned long completionBytes = 0;
6277 if (GlobalCodeCompletionAllocator *completionAllocator =
6278 astUnit->getCachedCompletionAllocator().getPtr()) {
6279 completionBytes = completionAllocator->getTotalMemory();
6280 }
6281 createCXTUResourceUsageEntry(*entries,
6282 CXTUResourceUsage_GlobalCompletionResults,
6283 completionBytes);
6284
6285 // How much memory is being used by SourceManager's content cache?
6286 createCXTUResourceUsageEntry(*entries,
6287 CXTUResourceUsage_SourceManagerContentCache,
6288 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6289
6290 // How much memory is being used by the MemoryBuffer's in SourceManager?
6291 const SourceManager::MemoryBufferSizes &srcBufs =
6292 astUnit->getSourceManager().getMemoryBufferSizes();
6293
6294 createCXTUResourceUsageEntry(*entries,
6295 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6296 (unsigned long) srcBufs.malloc_bytes);
6297 createCXTUResourceUsageEntry(*entries,
6298 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6299 (unsigned long) srcBufs.mmap_bytes);
6300 createCXTUResourceUsageEntry(*entries,
6301 CXTUResourceUsage_SourceManager_DataStructures,
6302 (unsigned long) astContext.getSourceManager()
6303 .getDataStructureSizes());
6304
6305 // How much memory is being used by the ExternalASTSource?
6306 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6307 const ExternalASTSource::MemoryBufferSizes &sizes =
6308 esrc->getMemoryBufferSizes();
6309
6310 createCXTUResourceUsageEntry(*entries,
6311 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6312 (unsigned long) sizes.malloc_bytes);
6313 createCXTUResourceUsageEntry(*entries,
6314 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6315 (unsigned long) sizes.mmap_bytes);
6316 }
6317
6318 // How much memory is being used by the Preprocessor?
6319 Preprocessor &pp = astUnit->getPreprocessor();
6320 createCXTUResourceUsageEntry(*entries,
6321 CXTUResourceUsage_Preprocessor,
6322 pp.getTotalMemory());
6323
6324 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6325 createCXTUResourceUsageEntry(*entries,
6326 CXTUResourceUsage_PreprocessingRecord,
6327 pRec->getTotalMemory());
6328 }
6329
6330 createCXTUResourceUsageEntry(*entries,
6331 CXTUResourceUsage_Preprocessor_HeaderSearch,
6332 pp.getHeaderSearchInfo().getTotalMemory());
6333
6334 CXTUResourceUsage usage = { (void*) entries.get(),
6335 (unsigned) entries->size(),
6336 entries->size() ? &(*entries)[0] : 0 };
6337 entries.take();
6338 return usage;
6339}
6340
6341void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6342 if (usage.data)
6343 delete (MemUsageEntries*) usage.data;
6344}
6345
6346} // end extern "C"
6347
6348void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6349 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6350 for (unsigned I = 0; I != Usage.numEntries; ++I)
6351 fprintf(stderr, " %s: %lu\n",
6352 clang_getTUResourceUsageName(Usage.entries[I].kind),
6353 Usage.entries[I].amount);
6354
6355 clang_disposeCXTUResourceUsage(Usage);
6356}
6357
6358//===----------------------------------------------------------------------===//
6359// Misc. utility functions.
6360//===----------------------------------------------------------------------===//
6361
6362/// Default to using an 8 MB stack size on "safety" threads.
6363static unsigned SafetyStackThreadSize = 8 << 20;
6364
6365namespace clang {
6366
6367bool RunSafely(llvm::CrashRecoveryContext &CRC,
6368 void (*Fn)(void*), void *UserData,
6369 unsigned Size) {
6370 if (!Size)
6371 Size = GetSafetyThreadStackSize();
6372 if (Size)
6373 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6374 return CRC.RunSafely(Fn, UserData);
6375}
6376
6377unsigned GetSafetyThreadStackSize() {
6378 return SafetyStackThreadSize;
6379}
6380
6381void SetSafetyThreadStackSize(unsigned Value) {
6382 SafetyStackThreadSize = Value;
6383}
6384
6385}
6386
6387void clang::setThreadBackgroundPriority() {
6388 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6389 return;
6390
6391 // FIXME: Move to llvm/Support and make it cross-platform.
6392#ifdef __APPLE__
6393 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6394#endif
6395}
6396
6397void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6398 if (!Unit)
6399 return;
6400
6401 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6402 DEnd = Unit->stored_diag_end();
6403 D != DEnd; ++D) {
6404 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6405 CXString Msg = clang_formatDiagnostic(&Diag,
6406 clang_defaultDiagnosticDisplayOptions());
6407 fprintf(stderr, "%s\n", clang_getCString(Msg));
6408 clang_disposeString(Msg);
6409 }
6410#ifdef LLVM_ON_WIN32
6411 // On Windows, force a flush, since there may be multiple copies of
6412 // stderr and stdout in the file system, all with different buffers
6413 // but writing to the same device.
6414 fflush(stderr);
6415#endif
6416}
6417
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006418MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6419 SourceLocation MacroDefLoc,
6420 CXTranslationUnit TU){
6421 if (MacroDefLoc.isInvalid() || !TU)
6422 return 0;
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006423 if (!II.hadMacroDefinition())
6424 return 0;
6425
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006426 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00006427 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006428 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006429 if (MD) {
6430 for (MacroDirective::DefInfo
6431 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6432 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6433 return Def.getMacroInfo();
6434 }
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006435 }
6436
6437 return 0;
6438}
6439
Dmitri Gribenko67812b22013-01-11 21:01:49 +00006440const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6441 CXTranslationUnit TU) {
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006442 if (!MacroDef || !TU)
6443 return 0;
6444 const IdentifierInfo *II = MacroDef->getName();
6445 if (!II)
6446 return 0;
6447
6448 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6449}
6450
6451MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6452 const Token &Tok,
6453 CXTranslationUnit TU) {
6454 if (!MI || !TU)
6455 return 0;
6456 if (Tok.isNot(tok::raw_identifier))
6457 return 0;
6458
6459 if (MI->getNumTokens() == 0)
6460 return 0;
6461 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6462 MI->getDefinitionEndLoc());
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006463 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006464
6465 // Check that the token is inside the definition and not its argument list.
6466 SourceManager &SM = Unit->getSourceManager();
6467 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6468 return 0;
6469 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6470 return 0;
6471
6472 Preprocessor &PP = Unit->getPreprocessor();
6473 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6474 if (!PPRec)
6475 return 0;
6476
6477 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6478 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6479 if (!II.hadMacroDefinition())
6480 return 0;
6481
6482 // Check that the identifier is not one of the macro arguments.
6483 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6484 return 0;
6485
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006486 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6487 if (!InnerMD)
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006488 return 0;
6489
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006490 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006491}
6492
6493MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6494 SourceLocation Loc,
6495 CXTranslationUnit TU) {
6496 if (Loc.isInvalid() || !MI || !TU)
6497 return 0;
6498
6499 if (MI->getNumTokens() == 0)
6500 return 0;
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006501 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006502 Preprocessor &PP = Unit->getPreprocessor();
6503 if (!PP.getPreprocessingRecord())
6504 return 0;
6505 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6506 Token Tok;
6507 if (PP.getRawToken(Loc, Tok))
6508 return 0;
6509
6510 return checkForMacroInMacroDefinition(MI, Tok, TU);
6511}
6512
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006513extern "C" {
6514
6515CXString clang_getClangVersion() {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006516 return cxstring::createDup(getClangFullVersion());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006517}
6518
6519} // end: extern "C"
6520
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006521Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6522 if (TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006523 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006524 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis44f65a52013-03-05 20:21:14 +00006525 if (Unit->isMainFileAST())
6526 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006527 return *this;
6528 }
6529 }
6530
6531 LogOS << "<NULL TU>";
6532 return *this;
6533}
6534
Argyrios Kyrtzidisb70e7a82013-03-08 02:32:26 +00006535Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6536 *this << FE->getName();
6537 return *this;
6538}
6539
6540Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6541 CXString cursorName = clang_getCursorDisplayName(cursor);
6542 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6543 clang_disposeString(cursorName);
6544 return *this;
6545}
6546
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006547Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6548 CXFile File;
6549 unsigned Line, Column;
6550 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6551 CXString FileName = clang_getFileName(File);
6552 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6553 clang_disposeString(FileName);
6554 return *this;
6555}
6556
6557Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6558 CXSourceLocation BLoc = clang_getRangeStart(range);
6559 CXSourceLocation ELoc = clang_getRangeEnd(range);
6560
6561 CXFile BFile;
6562 unsigned BLine, BColumn;
6563 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6564
6565 CXFile EFile;
6566 unsigned ELine, EColumn;
6567 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6568
6569 CXString BFileName = clang_getFileName(BFile);
6570 if (BFile == EFile) {
6571 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6572 BLine, BColumn, ELine, EColumn);
6573 } else {
6574 CXString EFileName = clang_getFileName(EFile);
6575 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6576 BLine, BColumn)
6577 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6578 ELine, EColumn);
6579 clang_disposeString(EFileName);
6580 }
6581 clang_disposeString(BFileName);
6582 return *this;
6583}
6584
6585Logger &cxindex::Logger::operator<<(CXString Str) {
6586 *this << clang_getCString(Str);
6587 return *this;
6588}
6589
6590Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6591 LogOS << Fmt;
6592 return *this;
6593}
6594
6595cxindex::Logger::~Logger() {
6596 LogOS.flush();
6597
6598 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6599
6600 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6601
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00006602 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006603 OS << "[libclang:" << Name << ':';
6604
6605 // FIXME: Portability.
6606#if HAVE_PTHREAD_H && __APPLE__
6607 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6608 OS << tid << ':';
6609#endif
6610
6611 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6612 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6613 OS << Msg.str() << '\n';
6614
6615 if (Trace) {
6616 llvm::sys::PrintStackTrace(stderr);
6617 OS << "--------------------------------------------------\n";
6618 }
6619}