blob: 09bb0eba8f5e60493ca55a666e93b6e98773de00 [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
Reid Kleckner12df2462013-06-24 17:51:48 +00001549bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1550 return Visit(TL.getOriginalLoc());
1551}
1552
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001553bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1554 TemplateSpecializationTypeLoc TL) {
1555 // Visit the template name.
1556 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1557 TL.getTemplateNameLoc()))
1558 return true;
1559
1560 // Visit the template arguments.
1561 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1562 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1563 return true;
1564
1565 return false;
1566}
1567
1568bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1569 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1570}
1571
1572bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1573 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1574 return Visit(TSInfo->getTypeLoc());
1575
1576 return false;
1577}
1578
1579bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1580 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1581 return Visit(TSInfo->getTypeLoc());
1582
1583 return false;
1584}
1585
1586bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1587 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1588 return true;
1589
1590 return false;
1591}
1592
1593bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1594 DependentTemplateSpecializationTypeLoc TL) {
1595 // Visit the nested-name-specifier, if there is one.
1596 if (TL.getQualifierLoc() &&
1597 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1598 return true;
1599
1600 // Visit the template arguments.
1601 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1602 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1603 return true;
1604
1605 return false;
1606}
1607
1608bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1609 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1610 return true;
1611
1612 return Visit(TL.getNamedTypeLoc());
1613}
1614
1615bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1616 return Visit(TL.getPatternLoc());
1617}
1618
1619bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1620 if (Expr *E = TL.getUnderlyingExpr())
1621 return Visit(MakeCXCursor(E, StmtParent, TU));
1622
1623 return false;
1624}
1625
1626bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1627 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1628}
1629
1630bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1631 return Visit(TL.getValueLoc());
1632}
1633
1634#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1635bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1636 return Visit##PARENT##Loc(TL); \
1637}
1638
1639DEFAULT_TYPELOC_IMPL(Complex, Type)
1640DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1641DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1642DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1643DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1644DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1645DEFAULT_TYPELOC_IMPL(Vector, Type)
1646DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1647DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1648DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1649DEFAULT_TYPELOC_IMPL(Record, TagType)
1650DEFAULT_TYPELOC_IMPL(Enum, TagType)
1651DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1652DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1653DEFAULT_TYPELOC_IMPL(Auto, Type)
1654
1655bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1656 // Visit the nested-name-specifier, if present.
1657 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1658 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1659 return true;
1660
1661 if (D->isCompleteDefinition()) {
1662 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1663 E = D->bases_end(); I != E; ++I) {
1664 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1665 return true;
1666 }
1667 }
1668
1669 return VisitTagDecl(D);
1670}
1671
1672bool CursorVisitor::VisitAttributes(Decl *D) {
1673 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1674 i != e; ++i)
1675 if (Visit(MakeCXCursor(*i, D, TU)))
1676 return true;
1677
1678 return false;
1679}
1680
1681//===----------------------------------------------------------------------===//
1682// Data-recursive visitor methods.
1683//===----------------------------------------------------------------------===//
1684
1685namespace {
1686#define DEF_JOB(NAME, DATA, KIND)\
1687class NAME : public VisitorJob {\
1688public:\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001689 NAME(const DATA *d, CXCursor parent) : \
1690 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001691 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001692 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001693};
1694
1695DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1696DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1697DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1698DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1699DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1700 ExplicitTemplateArgsVisitKind)
1701DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1702DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1703DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1704#undef DEF_JOB
1705
1706class DeclVisit : public VisitorJob {
1707public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001708 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001709 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001710 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001711 static bool classof(const VisitorJob *VJ) {
1712 return VJ->getKind() == DeclVisitKind;
1713 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001714 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001715 bool isFirst() const { return data[1] ? true : false; }
1716};
1717class TypeLocVisit : public VisitorJob {
1718public:
1719 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1720 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1721 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1722
1723 static bool classof(const VisitorJob *VJ) {
1724 return VJ->getKind() == TypeLocVisitKind;
1725 }
1726
1727 TypeLoc get() const {
1728 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001729 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001730 }
1731};
1732
1733class LabelRefVisit : public VisitorJob {
1734public:
1735 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1736 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1737 labelLoc.getPtrEncoding()) {}
1738
1739 static bool classof(const VisitorJob *VJ) {
1740 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1741 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001742 const LabelDecl *get() const {
1743 return static_cast<const LabelDecl *>(data[0]);
1744 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001745 SourceLocation getLoc() const {
1746 return SourceLocation::getFromPtrEncoding(data[1]); }
1747};
1748
1749class NestedNameSpecifierLocVisit : public VisitorJob {
1750public:
1751 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1752 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1753 Qualifier.getNestedNameSpecifier(),
1754 Qualifier.getOpaqueData()) { }
1755
1756 static bool classof(const VisitorJob *VJ) {
1757 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1758 }
1759
1760 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001761 return NestedNameSpecifierLoc(
1762 const_cast<NestedNameSpecifier *>(
1763 static_cast<const NestedNameSpecifier *>(data[0])),
1764 const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001765 }
1766};
1767
1768class DeclarationNameInfoVisit : public VisitorJob {
1769public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001770 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001771 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001772 static bool classof(const VisitorJob *VJ) {
1773 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1774 }
1775 DeclarationNameInfo get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001776 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001777 switch (S->getStmtClass()) {
1778 default:
1779 llvm_unreachable("Unhandled Stmt");
1780 case clang::Stmt::MSDependentExistsStmtClass:
1781 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1782 case Stmt::CXXDependentScopeMemberExprClass:
1783 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1784 case Stmt::DependentScopeDeclRefExprClass:
1785 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1786 }
1787 }
1788};
1789class MemberRefVisit : public VisitorJob {
1790public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001791 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001792 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1793 L.getPtrEncoding()) {}
1794 static bool classof(const VisitorJob *VJ) {
1795 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1796 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001797 const FieldDecl *get() const {
1798 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001799 }
1800 SourceLocation getLoc() const {
1801 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1802 }
1803};
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001804class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001805 VisitorWorkList &WL;
1806 CXCursor Parent;
1807public:
1808 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1809 : WL(wl), Parent(parent) {}
1810
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001811 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1812 void VisitBlockExpr(const BlockExpr *B);
1813 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1814 void VisitCompoundStmt(const CompoundStmt *S);
1815 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1816 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1817 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1818 void VisitCXXNewExpr(const CXXNewExpr *E);
1819 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1820 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1821 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1822 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1823 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1824 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1825 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1826 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1827 void VisitDeclRefExpr(const DeclRefExpr *D);
1828 void VisitDeclStmt(const DeclStmt *S);
1829 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1830 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1831 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1832 void VisitForStmt(const ForStmt *FS);
1833 void VisitGotoStmt(const GotoStmt *GS);
1834 void VisitIfStmt(const IfStmt *If);
1835 void VisitInitListExpr(const InitListExpr *IE);
1836 void VisitMemberExpr(const MemberExpr *M);
1837 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1838 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1839 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1840 void VisitOverloadExpr(const OverloadExpr *E);
1841 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1842 void VisitStmt(const Stmt *S);
1843 void VisitSwitchStmt(const SwitchStmt *S);
1844 void VisitWhileStmt(const WhileStmt *W);
1845 void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E);
1846 void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E);
1847 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1848 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1849 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1850 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1851 void VisitVAArgExpr(const VAArgExpr *E);
1852 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1853 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1854 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1855 void VisitLambdaExpr(const LambdaExpr *E);
1856
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001857private:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001858 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001859 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1860 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001861 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1862 void AddStmt(const Stmt *S);
1863 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001864 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001865 void EnqueueChildren(const Stmt *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001866};
1867} // end anonyous namespace
1868
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001869void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001870 // 'S' should always be non-null, since it comes from the
1871 // statement we are visiting.
1872 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1873}
1874
1875void
1876EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1877 if (Qualifier)
1878 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1879}
1880
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001881void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001882 if (S)
1883 WL.push_back(StmtVisit(S, Parent));
1884}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001885void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001886 if (D)
1887 WL.push_back(DeclVisit(D, Parent, isFirst));
1888}
1889void EnqueueVisitor::
1890 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1891 if (A)
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001892 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001893}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001894void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001895 if (D)
1896 WL.push_back(MemberRefVisit(D, L, Parent));
1897}
1898void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1899 if (TI)
1900 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1901 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001902void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001903 unsigned size = WL.size();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001904 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001905 AddStmt(*Child);
1906 }
1907 if (size == WL.size())
1908 return;
1909 // Now reverse the entries we just added. This will match the DFS
1910 // ordering performed by the worklist.
1911 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1912 std::reverse(I, E);
1913}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001914void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001915 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1916}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001917void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001918 AddDecl(B->getBlockDecl());
1919}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001920void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001921 EnqueueChildren(E);
1922 AddTypeLoc(E->getTypeSourceInfo());
1923}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001924void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1925 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001926 E = S->body_rend(); I != E; ++I) {
1927 AddStmt(*I);
1928 }
1929}
1930void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001931VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001932 AddStmt(S->getSubStmt());
1933 AddDeclarationNameInfo(S);
1934 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1935 AddNestedNameSpecifierLoc(QualifierLoc);
1936}
1937
1938void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001939VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001940 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1941 AddDeclarationNameInfo(E);
1942 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1943 AddNestedNameSpecifierLoc(QualifierLoc);
1944 if (!E->isImplicitAccess())
1945 AddStmt(E->getBase());
1946}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001947void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001948 // Enqueue the initializer , if any.
1949 AddStmt(E->getInitializer());
1950 // Enqueue the array size, if any.
1951 AddStmt(E->getArraySize());
1952 // Enqueue the allocated type.
1953 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1954 // Enqueue the placement arguments.
1955 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1956 AddStmt(E->getPlacementArg(I-1));
1957}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001958void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001959 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1960 AddStmt(CE->getArg(I-1));
1961 AddStmt(CE->getCallee());
1962 AddStmt(CE->getArg(0));
1963}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001964void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
1965 const CXXPseudoDestructorExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001966 // Visit the name of the type being destroyed.
1967 AddTypeLoc(E->getDestroyedTypeInfo());
1968 // Visit the scope type that looks disturbingly like the nested-name-specifier
1969 // but isn't.
1970 AddTypeLoc(E->getScopeTypeInfo());
1971 // Visit the nested-name-specifier.
1972 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1973 AddNestedNameSpecifierLoc(QualifierLoc);
1974 // Visit base expression.
1975 AddStmt(E->getBase());
1976}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001977void EnqueueVisitor::VisitCXXScalarValueInitExpr(
1978 const CXXScalarValueInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001979 AddTypeLoc(E->getTypeSourceInfo());
1980}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001981void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
1982 const CXXTemporaryObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001983 EnqueueChildren(E);
1984 AddTypeLoc(E->getTypeSourceInfo());
1985}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001986void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001987 EnqueueChildren(E);
1988 if (E->isTypeOperand())
1989 AddTypeLoc(E->getTypeOperandSourceInfo());
1990}
1991
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001992void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
1993 const CXXUnresolvedConstructExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001994 EnqueueChildren(E);
1995 AddTypeLoc(E->getTypeSourceInfo());
1996}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001997void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001998 EnqueueChildren(E);
1999 if (E->isTypeOperand())
2000 AddTypeLoc(E->getTypeOperandSourceInfo());
2001}
2002
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002003void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002004 EnqueueChildren(S);
2005 AddDecl(S->getExceptionDecl());
2006}
2007
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002008void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002009 if (DR->hasExplicitTemplateArgs()) {
2010 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2011 }
2012 WL.push_back(DeclRefExprParts(DR, Parent));
2013}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002014void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2015 const DependentScopeDeclRefExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002016 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2017 AddDeclarationNameInfo(E);
2018 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2019}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002020void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002021 unsigned size = WL.size();
2022 bool isFirst = true;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002023 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002024 D != DEnd; ++D) {
2025 AddDecl(*D, isFirst);
2026 isFirst = false;
2027 }
2028 if (size == WL.size())
2029 return;
2030 // Now reverse the entries we just added. This will match the DFS
2031 // ordering performed by the worklist.
2032 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2033 std::reverse(I, E);
2034}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002035void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002036 AddStmt(E->getInit());
2037 typedef DesignatedInitExpr::Designator Designator;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002038 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002039 D = E->designators_rbegin(), DEnd = E->designators_rend();
2040 D != DEnd; ++D) {
2041 if (D->isFieldDesignator()) {
2042 if (FieldDecl *Field = D->getField())
2043 AddMemberRef(Field, D->getFieldLoc());
2044 continue;
2045 }
2046 if (D->isArrayDesignator()) {
2047 AddStmt(E->getArrayIndex(*D));
2048 continue;
2049 }
2050 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2051 AddStmt(E->getArrayRangeEnd(*D));
2052 AddStmt(E->getArrayRangeStart(*D));
2053 }
2054}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002055void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002056 EnqueueChildren(E);
2057 AddTypeLoc(E->getTypeInfoAsWritten());
2058}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002059void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002060 AddStmt(FS->getBody());
2061 AddStmt(FS->getInc());
2062 AddStmt(FS->getCond());
2063 AddDecl(FS->getConditionVariable());
2064 AddStmt(FS->getInit());
2065}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002066void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002067 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2068}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002069void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002070 AddStmt(If->getElse());
2071 AddStmt(If->getThen());
2072 AddStmt(If->getCond());
2073 AddDecl(If->getConditionVariable());
2074}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002075void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002076 // We care about the syntactic form of the initializer list, only.
2077 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2078 IE = Syntactic;
2079 EnqueueChildren(IE);
2080}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002081void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002082 WL.push_back(MemberExprParts(M, Parent));
2083
2084 // If the base of the member access expression is an implicit 'this', don't
2085 // visit it.
2086 // FIXME: If we ever want to show these implicit accesses, this will be
2087 // unfortunate. However, clang_getCursor() relies on this behavior.
2088 if (!M->isImplicitAccess())
2089 AddStmt(M->getBase());
2090}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002091void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002092 AddTypeLoc(E->getEncodedTypeSourceInfo());
2093}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002094void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002095 EnqueueChildren(M);
2096 AddTypeLoc(M->getClassReceiverTypeInfo());
2097}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002098void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002099 // Visit the components of the offsetof expression.
2100 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2101 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2102 const OffsetOfNode &Node = E->getComponent(I-1);
2103 switch (Node.getKind()) {
2104 case OffsetOfNode::Array:
2105 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2106 break;
2107 case OffsetOfNode::Field:
2108 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2109 break;
2110 case OffsetOfNode::Identifier:
2111 case OffsetOfNode::Base:
2112 continue;
2113 }
2114 }
2115 // Visit the type into which we're computing the offset.
2116 AddTypeLoc(E->getTypeSourceInfo());
2117}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002118void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002119 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2120 WL.push_back(OverloadExprParts(E, Parent));
2121}
2122void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002123 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002124 EnqueueChildren(E);
2125 if (E->isArgumentType())
2126 AddTypeLoc(E->getArgumentTypeInfo());
2127}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002128void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002129 EnqueueChildren(S);
2130}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002131void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002132 AddStmt(S->getBody());
2133 AddStmt(S->getCond());
2134 AddDecl(S->getConditionVariable());
2135}
2136
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002137void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002138 AddStmt(W->getBody());
2139 AddStmt(W->getCond());
2140 AddDecl(W->getConditionVariable());
2141}
2142
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002143void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002144 AddTypeLoc(E->getQueriedTypeSourceInfo());
2145}
2146
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002147void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002148 AddTypeLoc(E->getRhsTypeSourceInfo());
2149 AddTypeLoc(E->getLhsTypeSourceInfo());
2150}
2151
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002152void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002153 for (unsigned I = E->getNumArgs(); I > 0; --I)
2154 AddTypeLoc(E->getArg(I-1));
2155}
2156
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002157void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002158 AddTypeLoc(E->getQueriedTypeSourceInfo());
2159}
2160
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002161void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002162 EnqueueChildren(E);
2163}
2164
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002165void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002166 VisitOverloadExpr(U);
2167 if (!U->isImplicitAccess())
2168 AddStmt(U->getBase());
2169}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002170void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002171 AddStmt(E->getSubExpr());
2172 AddTypeLoc(E->getWrittenTypeInfo());
2173}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002174void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002175 WL.push_back(SizeOfPackExprParts(E, Parent));
2176}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002177void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002178 // If the opaque value has a source expression, just transparently
2179 // visit that. This is useful for (e.g.) pseudo-object expressions.
2180 if (Expr *SourceExpr = E->getSourceExpr())
2181 return Visit(SourceExpr);
2182}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002183void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002184 AddStmt(E->getBody());
2185 WL.push_back(LambdaExprParts(E, Parent));
2186}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002187void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002188 // Treat the expression like its syntactic form.
2189 Visit(E->getSyntacticForm());
2190}
2191
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002192void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002193 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2194}
2195
2196bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2197 if (RegionOfInterest.isValid()) {
2198 SourceRange Range = getRawCursorExtent(C);
2199 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2200 return false;
2201 }
2202 return true;
2203}
2204
2205bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2206 while (!WL.empty()) {
2207 // Dequeue the worklist item.
2208 VisitorJob LI = WL.back();
2209 WL.pop_back();
2210
2211 // Set the Parent field, then back to its old value once we're done.
2212 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2213
2214 switch (LI.getKind()) {
2215 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002216 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002217 if (!D)
2218 continue;
2219
2220 // For now, perform default visitation for Decls.
2221 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2222 cast<DeclVisit>(&LI)->isFirst())))
2223 return true;
2224
2225 continue;
2226 }
2227 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2228 const ASTTemplateArgumentListInfo *ArgList =
2229 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2230 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2231 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2232 Arg != ArgEnd; ++Arg) {
2233 if (VisitTemplateArgumentLoc(*Arg))
2234 return true;
2235 }
2236 continue;
2237 }
2238 case VisitorJob::TypeLocVisitKind: {
2239 // Perform default visitation for TypeLocs.
2240 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2241 return true;
2242 continue;
2243 }
2244 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002245 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002246 if (LabelStmt *stmt = LS->getStmt()) {
2247 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2248 TU))) {
2249 return true;
2250 }
2251 }
2252 continue;
2253 }
2254
2255 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2256 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2257 if (VisitNestedNameSpecifierLoc(V->get()))
2258 return true;
2259 continue;
2260 }
2261
2262 case VisitorJob::DeclarationNameInfoVisitKind: {
2263 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2264 ->get()))
2265 return true;
2266 continue;
2267 }
2268 case VisitorJob::MemberRefVisitKind: {
2269 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2270 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2271 return true;
2272 continue;
2273 }
2274 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002275 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002276 if (!S)
2277 continue;
2278
2279 // Update the current cursor.
2280 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2281 if (!IsInRegionOfInterest(Cursor))
2282 continue;
2283 switch (Visitor(Cursor, Parent, ClientData)) {
2284 case CXChildVisit_Break: return true;
2285 case CXChildVisit_Continue: break;
2286 case CXChildVisit_Recurse:
2287 if (PostChildrenVisitor)
2288 WL.push_back(PostChildrenVisit(0, Cursor));
2289 EnqueueWorkList(WL, S);
2290 break;
2291 }
2292 continue;
2293 }
2294 case VisitorJob::MemberExprPartsKind: {
2295 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002296 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002297
2298 // Visit the nested-name-specifier
2299 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2300 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2301 return true;
2302
2303 // Visit the declaration name.
2304 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2305 return true;
2306
2307 // Visit the explicitly-specified template arguments, if any.
2308 if (M->hasExplicitTemplateArgs()) {
2309 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2310 *ArgEnd = Arg + M->getNumTemplateArgs();
2311 Arg != ArgEnd; ++Arg) {
2312 if (VisitTemplateArgumentLoc(*Arg))
2313 return true;
2314 }
2315 }
2316 continue;
2317 }
2318 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002319 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002320 // Visit nested-name-specifier, if present.
2321 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2322 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2323 return true;
2324 // Visit declaration name.
2325 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2326 return true;
2327 continue;
2328 }
2329 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002330 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002331 // Visit the nested-name-specifier.
2332 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2333 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2334 return true;
2335 // Visit the declaration name.
2336 if (VisitDeclarationNameInfo(O->getNameInfo()))
2337 return true;
2338 // Visit the overloaded declaration reference.
2339 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2340 return true;
2341 continue;
2342 }
2343 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002344 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002345 NamedDecl *Pack = E->getPack();
2346 if (isa<TemplateTypeParmDecl>(Pack)) {
2347 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2348 E->getPackLoc(), TU)))
2349 return true;
2350
2351 continue;
2352 }
2353
2354 if (isa<TemplateTemplateParmDecl>(Pack)) {
2355 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2356 E->getPackLoc(), TU)))
2357 return true;
2358
2359 continue;
2360 }
2361
2362 // Non-type template parameter packs and function parameter packs are
2363 // treated like DeclRefExpr cursors.
2364 continue;
2365 }
2366
2367 case VisitorJob::LambdaExprPartsKind: {
2368 // Visit captures.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002369 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002370 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2371 CEnd = E->explicit_capture_end();
2372 C != CEnd; ++C) {
Richard Smith0d8e9642013-05-16 06:20:58 +00002373 // FIXME: Lambda init-captures.
2374 if (!C->capturesVariable())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002375 continue;
Richard Smith0d8e9642013-05-16 06:20:58 +00002376
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002377 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2378 C->getLocation(),
2379 TU)))
2380 return true;
2381 }
2382
2383 // Visit parameters and return type, if present.
2384 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2385 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2386 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2387 // Visit the whole type.
2388 if (Visit(TL))
2389 return true;
David Blaikie39e6ab42013-02-18 22:06:02 +00002390 } else if (FunctionProtoTypeLoc Proto =
2391 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002392 if (E->hasExplicitParameters()) {
2393 // Visit parameters.
2394 for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
2395 if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
2396 return true;
2397 } else {
2398 // Visit result type.
2399 if (Visit(Proto.getResultLoc()))
2400 return true;
2401 }
2402 }
2403 }
2404 break;
2405 }
2406
2407 case VisitorJob::PostChildrenVisitKind:
2408 if (PostChildrenVisitor(Parent, ClientData))
2409 return true;
2410 break;
2411 }
2412 }
2413 return false;
2414}
2415
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002416bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002417 VisitorWorkList *WL = 0;
2418 if (!WorkListFreeList.empty()) {
2419 WL = WorkListFreeList.back();
2420 WL->clear();
2421 WorkListFreeList.pop_back();
2422 }
2423 else {
2424 WL = new VisitorWorkList();
2425 WorkListCache.push_back(WL);
2426 }
2427 EnqueueWorkList(*WL, S);
2428 bool result = RunVisitorWorkList(*WL);
2429 WorkListFreeList.push_back(WL);
2430 return result;
2431}
2432
2433namespace {
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00002434typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002435RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2436 const DeclarationNameInfo &NI,
2437 const SourceRange &QLoc,
2438 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2439 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2440 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2441 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2442
2443 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2444
2445 RefNamePieces Pieces;
2446
2447 if (WantQualifier && QLoc.isValid())
2448 Pieces.push_back(QLoc);
2449
2450 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2451 Pieces.push_back(NI.getLoc());
2452
2453 if (WantTemplateArgs && TemplateArgs)
2454 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2455 TemplateArgs->RAngleLoc));
2456
2457 if (Kind == DeclarationName::CXXOperatorName) {
2458 Pieces.push_back(SourceLocation::getFromRawEncoding(
2459 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2460 Pieces.push_back(SourceLocation::getFromRawEncoding(
2461 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2462 }
2463
2464 if (WantSinglePiece) {
2465 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2466 Pieces.clear();
2467 Pieces.push_back(R);
2468 }
2469
2470 return Pieces;
2471}
2472}
2473
2474//===----------------------------------------------------------------------===//
2475// Misc. API hooks.
2476//===----------------------------------------------------------------------===//
2477
2478static llvm::sys::Mutex EnableMultithreadingMutex;
2479static bool EnabledMultithreading;
2480
Chad Rosier90836282013-03-27 18:28:23 +00002481static void fatal_error_handler(void *user_data, const std::string& reason,
2482 bool gen_crash_diag) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002483 // Write the result out to stderr avoiding errs() because raw_ostreams can
2484 // call report_fatal_error.
2485 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2486 ::abort();
2487}
2488
2489extern "C" {
2490CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2491 int displayDiagnostics) {
2492 // Disable pretty stack trace functionality, which will otherwise be a very
2493 // poor citizen of the world and set up all sorts of signal handlers.
2494 llvm::DisablePrettyStackTrace = true;
2495
2496 // We use crash recovery to make some of our APIs more reliable, implicitly
2497 // enable it.
2498 llvm::CrashRecoveryContext::Enable();
2499
2500 // Enable support for multithreading in LLVM.
2501 {
2502 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2503 if (!EnabledMultithreading) {
2504 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2505 llvm::llvm_start_multithreaded();
2506 EnabledMultithreading = true;
2507 }
2508 }
2509
2510 CIndexer *CIdxr = new CIndexer();
2511 if (excludeDeclarationsFromPCH)
2512 CIdxr->setOnlyLocalDecls();
2513 if (displayDiagnostics)
2514 CIdxr->setDisplayDiagnostics();
2515
2516 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2517 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2518 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2519 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2520 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2521 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2522
2523 return CIdxr;
2524}
2525
2526void clang_disposeIndex(CXIndex CIdx) {
2527 if (CIdx)
2528 delete static_cast<CIndexer *>(CIdx);
2529}
2530
2531void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2532 if (CIdx)
2533 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2534}
2535
2536unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2537 if (CIdx)
2538 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2539 return 0;
2540}
2541
2542void clang_toggleCrashRecovery(unsigned isEnabled) {
2543 if (isEnabled)
2544 llvm::CrashRecoveryContext::Enable();
2545 else
2546 llvm::CrashRecoveryContext::Disable();
2547}
2548
2549CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2550 const char *ast_filename) {
Argyrios Kyrtzidis4c9f58f2013-05-24 22:24:07 +00002551 if (!CIdx || !ast_filename)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002552 return 0;
2553
Argyrios Kyrtzidis4c9f58f2013-05-24 22:24:07 +00002554 LOG_FUNC_SECTION {
2555 *Log << ast_filename;
2556 }
2557
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002558 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2559 FileSystemOptions FileSystemOpts;
2560
2561 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2562 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2563 CXXIdx->getOnlyLocalDecls(),
2564 0, 0,
2565 /*CaptureDiagnostics=*/true,
2566 /*AllowPCHWithCompilerErrors=*/true,
2567 /*UserFilesAreVolatile=*/true);
2568 return MakeCXTranslationUnit(CXXIdx, TU);
2569}
2570
2571unsigned clang_defaultEditingTranslationUnitOptions() {
2572 return CXTranslationUnit_PrecompiledPreamble |
2573 CXTranslationUnit_CacheCompletionResults;
2574}
2575
2576CXTranslationUnit
2577clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2578 const char *source_filename,
2579 int num_command_line_args,
2580 const char * const *command_line_args,
2581 unsigned num_unsaved_files,
2582 struct CXUnsavedFile *unsaved_files) {
2583 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2584 return clang_parseTranslationUnit(CIdx, source_filename,
2585 command_line_args, num_command_line_args,
2586 unsaved_files, num_unsaved_files,
2587 Options);
2588}
2589
2590struct ParseTranslationUnitInfo {
2591 CXIndex CIdx;
2592 const char *source_filename;
2593 const char *const *command_line_args;
2594 int num_command_line_args;
2595 struct CXUnsavedFile *unsaved_files;
2596 unsigned num_unsaved_files;
2597 unsigned options;
2598 CXTranslationUnit result;
2599};
2600static void clang_parseTranslationUnit_Impl(void *UserData) {
2601 ParseTranslationUnitInfo *PTUI =
2602 static_cast<ParseTranslationUnitInfo*>(UserData);
2603 CXIndex CIdx = PTUI->CIdx;
2604 const char *source_filename = PTUI->source_filename;
2605 const char * const *command_line_args = PTUI->command_line_args;
2606 int num_command_line_args = PTUI->num_command_line_args;
2607 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2608 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2609 unsigned options = PTUI->options;
2610 PTUI->result = 0;
2611
2612 if (!CIdx)
2613 return;
2614
2615 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2616
2617 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2618 setThreadBackgroundPriority();
2619
2620 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2621 // FIXME: Add a flag for modules.
2622 TranslationUnitKind TUKind
2623 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
2624 bool CacheCodeCompetionResults
2625 = options & CXTranslationUnit_CacheCompletionResults;
2626 bool IncludeBriefCommentsInCodeCompletion
2627 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2628 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2629 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2630
2631 // Configure the diagnostics.
2632 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvad47afb92013-01-20 01:58:28 +00002633 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002634
2635 // Recover resources if we crash before exiting this function.
2636 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2637 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2638 DiagCleanup(Diags.getPtr());
2639
2640 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2641 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2642
2643 // Recover resources if we crash before exiting this function.
2644 llvm::CrashRecoveryContextCleanupRegistrar<
2645 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2646
2647 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2648 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2649 const llvm::MemoryBuffer *Buffer
2650 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2651 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2652 Buffer));
2653 }
2654
2655 OwningPtr<std::vector<const char *> >
2656 Args(new std::vector<const char*>());
2657
2658 // Recover resources if we crash before exiting this method.
2659 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2660 ArgsCleanup(Args.get());
2661
2662 // Since the Clang C library is primarily used by batch tools dealing with
2663 // (often very broken) source code, where spell-checking can have a
2664 // significant negative impact on performance (particularly when
2665 // precompiled headers are involved), we disable it by default.
2666 // Only do this if we haven't found a spell-checking-related argument.
2667 bool FoundSpellCheckingArgument = false;
2668 for (int I = 0; I != num_command_line_args; ++I) {
2669 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2670 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2671 FoundSpellCheckingArgument = true;
2672 break;
2673 }
2674 }
2675 if (!FoundSpellCheckingArgument)
2676 Args->push_back("-fno-spell-checking");
2677
2678 Args->insert(Args->end(), command_line_args,
2679 command_line_args + num_command_line_args);
2680
2681 // The 'source_filename' argument is optional. If the caller does not
2682 // specify it then it is assumed that the source file is specified
2683 // in the actual argument list.
2684 // Put the source file after command_line_args otherwise if '-x' flag is
2685 // present it will be unused.
2686 if (source_filename)
2687 Args->push_back(source_filename);
2688
2689 // Do we need the detailed preprocessing record?
2690 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2691 Args->push_back("-Xclang");
2692 Args->push_back("-detailed-preprocessing-record");
2693 }
2694
2695 unsigned NumErrors = Diags->getClient()->getNumErrors();
2696 OwningPtr<ASTUnit> ErrUnit;
2697 OwningPtr<ASTUnit> Unit(
2698 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2699 /* vector::data() not portable */,
2700 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2701 Diags,
2702 CXXIdx->getClangResourcesPath(),
2703 CXXIdx->getOnlyLocalDecls(),
2704 /*CaptureDiagnostics=*/true,
2705 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
2706 RemappedFiles->size(),
2707 /*RemappedFilesKeepOriginalName=*/true,
2708 PrecompilePreamble,
2709 TUKind,
2710 CacheCodeCompetionResults,
2711 IncludeBriefCommentsInCodeCompletion,
2712 /*AllowPCHWithCompilerErrors=*/true,
2713 SkipFunctionBodies,
2714 /*UserFilesAreVolatile=*/true,
2715 ForSerialization,
2716 &ErrUnit));
2717
2718 if (NumErrors != Diags->getClient()->getNumErrors()) {
2719 // Make sure to check that 'Unit' is non-NULL.
2720 if (CXXIdx->getDisplayDiagnostics())
2721 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2722 }
2723
2724 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2725}
2726CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2727 const char *source_filename,
2728 const char * const *command_line_args,
2729 int num_command_line_args,
2730 struct CXUnsavedFile *unsaved_files,
2731 unsigned num_unsaved_files,
2732 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002733 LOG_FUNC_SECTION {
2734 *Log << source_filename << ": ";
2735 for (int i = 0; i != num_command_line_args; ++i)
2736 *Log << command_line_args[i] << " ";
2737 }
2738
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002739 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2740 num_command_line_args, unsaved_files,
2741 num_unsaved_files, options, 0 };
2742 llvm::CrashRecoveryContext CRC;
2743
2744 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2745 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2746 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2747 fprintf(stderr, " 'command_line_args' : [");
2748 for (int i = 0; i != num_command_line_args; ++i) {
2749 if (i)
2750 fprintf(stderr, ", ");
2751 fprintf(stderr, "'%s'", command_line_args[i]);
2752 }
2753 fprintf(stderr, "],\n");
2754 fprintf(stderr, " 'unsaved_files' : [");
2755 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2756 if (i)
2757 fprintf(stderr, ", ");
2758 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2759 unsaved_files[i].Length);
2760 }
2761 fprintf(stderr, "],\n");
2762 fprintf(stderr, " 'options' : %d,\n", options);
2763 fprintf(stderr, "}\n");
2764
2765 return 0;
2766 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2767 PrintLibclangResourceUsage(PTUI.result);
2768 }
2769
2770 return PTUI.result;
2771}
2772
2773unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2774 return CXSaveTranslationUnit_None;
2775}
2776
2777namespace {
2778
2779struct SaveTranslationUnitInfo {
2780 CXTranslationUnit TU;
2781 const char *FileName;
2782 unsigned options;
2783 CXSaveError result;
2784};
2785
2786}
2787
2788static void clang_saveTranslationUnit_Impl(void *UserData) {
2789 SaveTranslationUnitInfo *STUI =
2790 static_cast<SaveTranslationUnitInfo*>(UserData);
2791
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002792 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002793 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2794 setThreadBackgroundPriority();
2795
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002796 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002797 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2798}
2799
2800int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2801 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002802 LOG_FUNC_SECTION {
2803 *Log << TU << ' ' << FileName;
2804 }
2805
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002806 if (!TU)
2807 return CXSaveError_InvalidTU;
2808
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002809 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002810 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2811 if (!CXXUnit->hasSema())
2812 return CXSaveError_InvalidTU;
2813
2814 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2815
2816 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2817 getenv("LIBCLANG_NOTHREADS")) {
2818 clang_saveTranslationUnit_Impl(&STUI);
2819
2820 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2821 PrintLibclangResourceUsage(TU);
2822
2823 return STUI.result;
2824 }
2825
2826 // We have an AST that has invalid nodes due to compiler errors.
2827 // Use a crash recovery thread for protection.
2828
2829 llvm::CrashRecoveryContext CRC;
2830
2831 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2832 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2833 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2834 fprintf(stderr, " 'options' : %d,\n", options);
2835 fprintf(stderr, "}\n");
2836
2837 return CXSaveError_Unknown;
2838
2839 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2840 PrintLibclangResourceUsage(TU);
2841 }
2842
2843 return STUI.result;
2844}
2845
2846void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2847 if (CTUnit) {
2848 // If the translation unit has been marked as unsafe to free, just discard
2849 // it.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002850 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002851 return;
2852
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002853 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenko9c48d162013-01-26 22:44:19 +00002854 delete CTUnit->StringPool;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002855 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2856 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko337ee242013-01-26 21:39:50 +00002857 delete CTUnit->FormatContext;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002858 delete CTUnit;
2859 }
2860}
2861
2862unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2863 return CXReparse_None;
2864}
2865
2866struct ReparseTranslationUnitInfo {
2867 CXTranslationUnit TU;
2868 unsigned num_unsaved_files;
2869 struct CXUnsavedFile *unsaved_files;
2870 unsigned options;
2871 int result;
2872};
2873
2874static void clang_reparseTranslationUnit_Impl(void *UserData) {
2875 ReparseTranslationUnitInfo *RTUI =
2876 static_cast<ReparseTranslationUnitInfo*>(UserData);
2877 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisd7bf4a42013-01-16 18:13:00 +00002878 if (!TU)
2879 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002880
2881 // Reset the associated diagnostics.
2882 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2883 TU->Diagnostics = 0;
2884
2885 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2886 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2887 unsigned options = RTUI->options;
2888 (void) options;
2889 RTUI->result = 1;
2890
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002891 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002892 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2893 setThreadBackgroundPriority();
2894
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002895 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002896 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2897
2898 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2899 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2900
2901 // Recover resources if we crash before exiting this function.
2902 llvm::CrashRecoveryContextCleanupRegistrar<
2903 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2904
2905 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2906 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2907 const llvm::MemoryBuffer *Buffer
2908 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2909 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2910 Buffer));
2911 }
2912
2913 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2914 RemappedFiles->size()))
2915 RTUI->result = 0;
2916}
2917
2918int clang_reparseTranslationUnit(CXTranslationUnit TU,
2919 unsigned num_unsaved_files,
2920 struct CXUnsavedFile *unsaved_files,
2921 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002922 LOG_FUNC_SECTION {
2923 *Log << TU;
2924 }
2925
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002926 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2927 options, 0 };
2928
2929 if (getenv("LIBCLANG_NOTHREADS")) {
2930 clang_reparseTranslationUnit_Impl(&RTUI);
2931 return RTUI.result;
2932 }
2933
2934 llvm::CrashRecoveryContext CRC;
2935
2936 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2937 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002938 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002939 return 1;
2940 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2941 PrintLibclangResourceUsage(TU);
2942
2943 return RTUI.result;
2944}
2945
2946
2947CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
2948 if (!CTUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00002949 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002950
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002951 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00002952 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002953}
2954
2955CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00002956 if (!TU)
2957 return clang_getNullCursor();
2958
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002959 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002960 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
2961}
2962
2963} // end: extern "C"
2964
2965//===----------------------------------------------------------------------===//
2966// CXFile Operations.
2967//===----------------------------------------------------------------------===//
2968
2969extern "C" {
2970CXString clang_getFileName(CXFile SFile) {
2971 if (!SFile)
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00002972 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002973
2974 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00002975 return cxstring::createRef(FEnt->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002976}
2977
2978time_t clang_getFileTime(CXFile SFile) {
2979 if (!SFile)
2980 return 0;
2981
2982 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2983 return FEnt->getModificationTime();
2984}
2985
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002986CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
2987 if (!TU)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002988 return 0;
2989
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002990 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002991
2992 FileManager &FMgr = CXXUnit->getFileManager();
2993 return const_cast<FileEntry *>(FMgr.getFile(file_name));
2994}
2995
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002996unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
2997 if (!TU || !file)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002998 return 0;
2999
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003000 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003001 FileEntry *FEnt = static_cast<FileEntry *>(file);
3002 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3003 .isFileMultipleIncludeGuarded(FEnt);
3004}
3005
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00003006int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3007 if (!file || !outID)
3008 return 1;
3009
3010#ifdef LLVM_ON_WIN32
3011 return 1; // inodes not supported on windows.
3012#else
3013 FileEntry *FEnt = static_cast<FileEntry *>(file);
3014 outID->data[0] = FEnt->getDevice();
3015 outID->data[1] = FEnt->getInode();
3016 outID->data[2] = FEnt->getModificationTime();
3017 return 0;
3018#endif
3019}
3020
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003021} // end: extern "C"
3022
3023//===----------------------------------------------------------------------===//
3024// CXCursor Operations.
3025//===----------------------------------------------------------------------===//
3026
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003027static const Decl *getDeclFromExpr(const Stmt *E) {
3028 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003029 return getDeclFromExpr(CE->getSubExpr());
3030
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003031 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003032 return RefExpr->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003033 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003034 return ME->getMemberDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003035 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003036 return RE->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003037 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003038 if (PRE->isExplicitProperty())
3039 return PRE->getExplicitProperty();
3040 // It could be messaging both getter and setter as in:
3041 // ++myobj.myprop;
3042 // in which case prefer to associate the setter since it is less obvious
3043 // from inspecting the source that the setter is going to get called.
3044 if (PRE->isMessagingSetter())
3045 return PRE->getImplicitPropertySetter();
3046 return PRE->getImplicitPropertyGetter();
3047 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003048 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003049 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003050 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003051 if (Expr *Src = OVE->getSourceExpr())
3052 return getDeclFromExpr(Src);
3053
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003054 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003055 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003056 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003057 if (!CE->isElidable())
3058 return CE->getConstructor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003059 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003060 return OME->getMethodDecl();
3061
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003062 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003063 return PE->getProtocol();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003064 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003065 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3066 return NTTP->getParameterPack();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003067 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003068 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3069 isa<ParmVarDecl>(SizeOfPack->getPack()))
3070 return SizeOfPack->getPack();
3071
3072 return 0;
3073}
3074
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003075static SourceLocation getLocationFromExpr(const Expr *E) {
3076 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003077 return getLocationFromExpr(CE->getSubExpr());
3078
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003079 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003080 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003081 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003082 return DRE->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003083 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003084 return Member->getMemberLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003085 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003086 return Ivar->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003087 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003088 return SizeOfPack->getPackLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003089 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003090 return PropRef->getLocation();
3091
3092 return E->getLocStart();
3093}
3094
3095extern "C" {
3096
3097unsigned clang_visitChildren(CXCursor parent,
3098 CXCursorVisitor visitor,
3099 CXClientData client_data) {
3100 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3101 /*VisitPreprocessorLast=*/false);
3102 return CursorVis.VisitChildren(parent);
3103}
3104
3105#ifndef __has_feature
3106#define __has_feature(x) 0
3107#endif
3108#if __has_feature(blocks)
3109typedef enum CXChildVisitResult
3110 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3111
3112static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3113 CXClientData client_data) {
3114 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3115 return block(cursor, parent);
3116}
3117#else
3118// If we are compiled with a compiler that doesn't have native blocks support,
3119// define and call the block manually, so the
3120typedef struct _CXChildVisitResult
3121{
3122 void *isa;
3123 int flags;
3124 int reserved;
3125 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3126 CXCursor);
3127} *CXCursorVisitorBlock;
3128
3129static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3130 CXClientData client_data) {
3131 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3132 return block->invoke(block, cursor, parent);
3133}
3134#endif
3135
3136
3137unsigned clang_visitChildrenWithBlock(CXCursor parent,
3138 CXCursorVisitorBlock block) {
3139 return clang_visitChildren(parent, visitWithBlock, block);
3140}
3141
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003142static CXString getDeclSpelling(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003143 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003144 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003145
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003146 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003147 if (!ND) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003148 if (const ObjCPropertyImplDecl *PropImpl =
3149 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003150 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003151 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003152
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003153 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003154 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003155 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003156
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003157 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003158 }
3159
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003160 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003161 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003162
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003163 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003164 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3165 // and returns different names. NamedDecl returns the class name and
3166 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003167 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003168
3169 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003170 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003171
3172 SmallString<1024> S;
3173 llvm::raw_svector_ostream os(S);
3174 ND->printName(os);
3175
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003176 return cxstring::createDup(os.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003177}
3178
3179CXString clang_getCursorSpelling(CXCursor C) {
3180 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko46f92522013-01-11 19:28:44 +00003181 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003182
3183 if (clang_isReference(C.kind)) {
3184 switch (C.kind) {
3185 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003186 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003187 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003188 }
3189 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003190 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003191 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003192 }
3193 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003194 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003195 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003196 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003197 }
3198 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003199 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003200 return cxstring::createDup(B->getType().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003201 }
3202 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003203 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003204 assert(Type && "Missing type decl");
3205
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003206 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003207 getAsString());
3208 }
3209 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003210 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003211 assert(Template && "Missing template decl");
3212
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003213 return cxstring::createDup(Template->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003214 }
3215
3216 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003217 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003218 assert(NS && "Missing namespace decl");
3219
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003220 return cxstring::createDup(NS->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003221 }
3222
3223 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003224 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003225 assert(Field && "Missing member decl");
3226
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003227 return cxstring::createDup(Field->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003228 }
3229
3230 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003231 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003232 assert(Label && "Missing label");
3233
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003234 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003235 }
3236
3237 case CXCursor_OverloadedDeclRef: {
3238 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003239 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3240 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003241 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003242 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003243 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003244 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003245 return cxstring::createDup(E->getName().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003246 OverloadedTemplateStorage *Ovl
3247 = Storage.get<OverloadedTemplateStorage*>();
3248 if (Ovl->size() == 0)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003249 return cxstring::createEmpty();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003250 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003251 }
3252
3253 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003254 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003255 assert(Var && "Missing variable decl");
3256
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003257 return cxstring::createDup(Var->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003258 }
3259
3260 default:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003261 return cxstring::createRef("<not implemented>");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003262 }
3263 }
3264
3265 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003266 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003267 if (D)
3268 return getDeclSpelling(D);
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003269 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003270 }
3271
3272 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003273 const Stmt *S = getCursorStmt(C);
3274 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003275 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003276
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003277 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003278 }
3279
3280 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003281 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003282 ->getNameStart());
3283
3284 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003285 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003286 ->getNameStart());
3287
3288 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003289 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003290
3291 if (clang_isDeclaration(C.kind))
3292 return getDeclSpelling(getCursorDecl(C));
3293
3294 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003295 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003296 return cxstring::createDup(AA->getAnnotation());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003297 }
3298
3299 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003300 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003301 return cxstring::createDup(AA->getLabel());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003302 }
3303
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003304 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003305}
3306
3307CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3308 unsigned pieceIndex,
3309 unsigned options) {
3310 if (clang_Cursor_isNull(C))
3311 return clang_getNullRange();
3312
3313 ASTContext &Ctx = getCursorContext(C);
3314
3315 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003316 const Stmt *S = getCursorStmt(C);
3317 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003318 if (pieceIndex > 0)
3319 return clang_getNullRange();
3320 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3321 }
3322
3323 return clang_getNullRange();
3324 }
3325
3326 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003327 if (const ObjCMessageExpr *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003328 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3329 if (pieceIndex >= ME->getNumSelectorLocs())
3330 return clang_getNullRange();
3331 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3332 }
3333 }
3334
3335 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3336 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003337 if (const ObjCMethodDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003338 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3339 if (pieceIndex >= MD->getNumSelectorLocs())
3340 return clang_getNullRange();
3341 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3342 }
3343 }
3344
3345 if (C.kind == CXCursor_ObjCCategoryDecl ||
3346 C.kind == CXCursor_ObjCCategoryImplDecl) {
3347 if (pieceIndex > 0)
3348 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003349 if (const ObjCCategoryDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003350 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3351 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003352 if (const ObjCCategoryImplDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003353 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3354 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3355 }
3356
3357 if (C.kind == CXCursor_ModuleImportDecl) {
3358 if (pieceIndex > 0)
3359 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003360 if (const ImportDecl *ImportD =
3361 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003362 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3363 if (!Locs.empty())
3364 return cxloc::translateSourceRange(Ctx,
3365 SourceRange(Locs.front(), Locs.back()));
3366 }
3367 return clang_getNullRange();
3368 }
3369
3370 // FIXME: A CXCursor_InclusionDirective should give the location of the
3371 // filename, but we don't keep track of this.
3372
3373 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3374 // but we don't keep track of this.
3375
3376 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3377 // but we don't keep track of this.
3378
3379 // Default handling, give the location of the cursor.
3380
3381 if (pieceIndex > 0)
3382 return clang_getNullRange();
3383
3384 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3385 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3386 return cxloc::translateSourceRange(Ctx, Loc);
3387}
3388
3389CXString clang_getCursorDisplayName(CXCursor C) {
3390 if (!clang_isDeclaration(C.kind))
3391 return clang_getCursorSpelling(C);
3392
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003393 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003394 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003395 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003396
3397 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003398 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003399 D = FunTmpl->getTemplatedDecl();
3400
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003401 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003402 SmallString<64> Str;
3403 llvm::raw_svector_ostream OS(Str);
3404 OS << *Function;
3405 if (Function->getPrimaryTemplate())
3406 OS << "<>";
3407 OS << "(";
3408 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3409 if (I)
3410 OS << ", ";
3411 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3412 }
3413
3414 if (Function->isVariadic()) {
3415 if (Function->getNumParams())
3416 OS << ", ";
3417 OS << "...";
3418 }
3419 OS << ")";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003420 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003421 }
3422
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003423 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003424 SmallString<64> Str;
3425 llvm::raw_svector_ostream OS(Str);
3426 OS << *ClassTemplate;
3427 OS << "<";
3428 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3429 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3430 if (I)
3431 OS << ", ";
3432
3433 NamedDecl *Param = Params->getParam(I);
3434 if (Param->getIdentifier()) {
3435 OS << Param->getIdentifier()->getName();
3436 continue;
3437 }
3438
3439 // There is no parameter name, which makes this tricky. Try to come up
3440 // with something useful that isn't too long.
3441 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3442 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3443 else if (NonTypeTemplateParmDecl *NTTP
3444 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3445 OS << NTTP->getType().getAsString(Policy);
3446 else
3447 OS << "template<...> class";
3448 }
3449
3450 OS << ">";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003451 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003452 }
3453
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003454 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003455 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3456 // If the type was explicitly written, use that.
3457 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003458 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003459
Benjamin Kramer5eada842013-02-22 15:46:01 +00003460 SmallString<128> Str;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003461 llvm::raw_svector_ostream OS(Str);
3462 OS << *ClassSpec;
Benjamin Kramer5eada842013-02-22 15:46:01 +00003463 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003464 ClassSpec->getTemplateArgs().data(),
3465 ClassSpec->getTemplateArgs().size(),
3466 Policy);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003467 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003468 }
3469
3470 return clang_getCursorSpelling(C);
3471}
3472
3473CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3474 switch (Kind) {
3475 case CXCursor_FunctionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003476 return cxstring::createRef("FunctionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003477 case CXCursor_TypedefDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003478 return cxstring::createRef("TypedefDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003479 case CXCursor_EnumDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003480 return cxstring::createRef("EnumDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003481 case CXCursor_EnumConstantDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003482 return cxstring::createRef("EnumConstantDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003483 case CXCursor_StructDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003484 return cxstring::createRef("StructDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003485 case CXCursor_UnionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003486 return cxstring::createRef("UnionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003487 case CXCursor_ClassDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003488 return cxstring::createRef("ClassDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003489 case CXCursor_FieldDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003490 return cxstring::createRef("FieldDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003491 case CXCursor_VarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003492 return cxstring::createRef("VarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003493 case CXCursor_ParmDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003494 return cxstring::createRef("ParmDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003495 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003496 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003497 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003498 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003499 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003500 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003501 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003502 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003503 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003504 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003505 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003506 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003507 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003508 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003509 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003510 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003511 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003512 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003513 case CXCursor_CXXMethod:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003514 return cxstring::createRef("CXXMethod");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003515 case CXCursor_UnexposedDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003516 return cxstring::createRef("UnexposedDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003517 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003518 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003519 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003520 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003521 case CXCursor_ObjCClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003522 return cxstring::createRef("ObjCClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003523 case CXCursor_TypeRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003524 return cxstring::createRef("TypeRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003525 case CXCursor_TemplateRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003526 return cxstring::createRef("TemplateRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003527 case CXCursor_NamespaceRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003528 return cxstring::createRef("NamespaceRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003529 case CXCursor_MemberRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003530 return cxstring::createRef("MemberRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003531 case CXCursor_LabelRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003532 return cxstring::createRef("LabelRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003533 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003534 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003535 case CXCursor_VariableRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003536 return cxstring::createRef("VariableRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003537 case CXCursor_IntegerLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003538 return cxstring::createRef("IntegerLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003539 case CXCursor_FloatingLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003540 return cxstring::createRef("FloatingLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003541 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003542 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003543 case CXCursor_StringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003544 return cxstring::createRef("StringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003545 case CXCursor_CharacterLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003546 return cxstring::createRef("CharacterLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003547 case CXCursor_ParenExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003548 return cxstring::createRef("ParenExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003549 case CXCursor_UnaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003550 return cxstring::createRef("UnaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003551 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003552 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003553 case CXCursor_BinaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003554 return cxstring::createRef("BinaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003555 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003556 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003557 case CXCursor_ConditionalOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003558 return cxstring::createRef("ConditionalOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003559 case CXCursor_CStyleCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003560 return cxstring::createRef("CStyleCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003561 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003562 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003563 case CXCursor_InitListExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003564 return cxstring::createRef("InitListExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003565 case CXCursor_AddrLabelExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003566 return cxstring::createRef("AddrLabelExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003567 case CXCursor_StmtExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003568 return cxstring::createRef("StmtExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003569 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003570 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003571 case CXCursor_GNUNullExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003572 return cxstring::createRef("GNUNullExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003573 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003574 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003575 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003576 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003577 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003578 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003579 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003580 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003581 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003582 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003583 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003584 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003585 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003586 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003587 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003588 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003589 case CXCursor_CXXThisExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003590 return cxstring::createRef("CXXThisExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003591 case CXCursor_CXXThrowExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003592 return cxstring::createRef("CXXThrowExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003593 case CXCursor_CXXNewExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003594 return cxstring::createRef("CXXNewExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003595 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003596 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003597 case CXCursor_UnaryExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003598 return cxstring::createRef("UnaryExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003599 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003600 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003601 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003602 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisedab0472013-04-23 17:57:17 +00003603 case CXCursor_ObjCSelfExpr:
3604 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003605 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003606 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003607 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003608 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003609 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003610 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003611 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003612 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003613 case CXCursor_BlockExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003614 return cxstring::createRef("BlockExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003615 case CXCursor_PackExpansionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003616 return cxstring::createRef("PackExpansionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003617 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003618 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003619 case CXCursor_LambdaExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003620 return cxstring::createRef("LambdaExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003621 case CXCursor_UnexposedExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003622 return cxstring::createRef("UnexposedExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003623 case CXCursor_DeclRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003624 return cxstring::createRef("DeclRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003625 case CXCursor_MemberRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003626 return cxstring::createRef("MemberRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003627 case CXCursor_CallExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003628 return cxstring::createRef("CallExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003629 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003630 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003631 case CXCursor_UnexposedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003632 return cxstring::createRef("UnexposedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003633 case CXCursor_DeclStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003634 return cxstring::createRef("DeclStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003635 case CXCursor_LabelStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003636 return cxstring::createRef("LabelStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003637 case CXCursor_CompoundStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003638 return cxstring::createRef("CompoundStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003639 case CXCursor_CaseStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003640 return cxstring::createRef("CaseStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003641 case CXCursor_DefaultStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003642 return cxstring::createRef("DefaultStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003643 case CXCursor_IfStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003644 return cxstring::createRef("IfStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003645 case CXCursor_SwitchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003646 return cxstring::createRef("SwitchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003647 case CXCursor_WhileStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003648 return cxstring::createRef("WhileStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003649 case CXCursor_DoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003650 return cxstring::createRef("DoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003651 case CXCursor_ForStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003652 return cxstring::createRef("ForStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003653 case CXCursor_GotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003654 return cxstring::createRef("GotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003655 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003656 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003657 case CXCursor_ContinueStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003658 return cxstring::createRef("ContinueStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003659 case CXCursor_BreakStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003660 return cxstring::createRef("BreakStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003661 case CXCursor_ReturnStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003662 return cxstring::createRef("ReturnStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003663 case CXCursor_GCCAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003664 return cxstring::createRef("GCCAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003665 case CXCursor_MSAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003666 return cxstring::createRef("MSAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003667 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003668 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003669 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003670 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003671 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003672 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003673 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003674 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003675 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003676 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003677 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003678 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003679 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003680 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003681 case CXCursor_CXXCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003682 return cxstring::createRef("CXXCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003683 case CXCursor_CXXTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003684 return cxstring::createRef("CXXTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003685 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003686 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003687 case CXCursor_SEHTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003688 return cxstring::createRef("SEHTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003689 case CXCursor_SEHExceptStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003690 return cxstring::createRef("SEHExceptStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003691 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003692 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003693 case CXCursor_NullStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003694 return cxstring::createRef("NullStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003695 case CXCursor_InvalidFile:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003696 return cxstring::createRef("InvalidFile");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003697 case CXCursor_InvalidCode:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003698 return cxstring::createRef("InvalidCode");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003699 case CXCursor_NoDeclFound:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003700 return cxstring::createRef("NoDeclFound");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003701 case CXCursor_NotImplemented:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003702 return cxstring::createRef("NotImplemented");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003703 case CXCursor_TranslationUnit:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003704 return cxstring::createRef("TranslationUnit");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003705 case CXCursor_UnexposedAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003706 return cxstring::createRef("UnexposedAttr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003707 case CXCursor_IBActionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003708 return cxstring::createRef("attribute(ibaction)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003709 case CXCursor_IBOutletAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003710 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003711 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003712 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003713 case CXCursor_CXXFinalAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003714 return cxstring::createRef("attribute(final)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003715 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003716 return cxstring::createRef("attribute(override)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003717 case CXCursor_AnnotateAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003718 return cxstring::createRef("attribute(annotate)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003719 case CXCursor_AsmLabelAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003720 return cxstring::createRef("asm label");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003721 case CXCursor_PreprocessingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003722 return cxstring::createRef("preprocessing directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003723 case CXCursor_MacroDefinition:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003724 return cxstring::createRef("macro definition");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003725 case CXCursor_MacroExpansion:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003726 return cxstring::createRef("macro expansion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003727 case CXCursor_InclusionDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003728 return cxstring::createRef("inclusion directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003729 case CXCursor_Namespace:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003730 return cxstring::createRef("Namespace");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003731 case CXCursor_LinkageSpec:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003732 return cxstring::createRef("LinkageSpec");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003733 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003734 return cxstring::createRef("C++ base class specifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003735 case CXCursor_Constructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003736 return cxstring::createRef("CXXConstructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003737 case CXCursor_Destructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003738 return cxstring::createRef("CXXDestructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003739 case CXCursor_ConversionFunction:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003740 return cxstring::createRef("CXXConversion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003741 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003742 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003743 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003744 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003745 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003746 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003747 case CXCursor_FunctionTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003748 return cxstring::createRef("FunctionTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003749 case CXCursor_ClassTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003750 return cxstring::createRef("ClassTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003751 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003752 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003753 case CXCursor_NamespaceAlias:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003754 return cxstring::createRef("NamespaceAlias");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003755 case CXCursor_UsingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003756 return cxstring::createRef("UsingDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003757 case CXCursor_UsingDeclaration:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003758 return cxstring::createRef("UsingDeclaration");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003759 case CXCursor_TypeAliasDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003760 return cxstring::createRef("TypeAliasDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003761 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003762 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003763 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003764 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003765 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003766 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003767 case CXCursor_ModuleImportDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003768 return cxstring::createRef("ModuleImport");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003769 }
3770
3771 llvm_unreachable("Unhandled CXCursorKind");
3772}
3773
3774struct GetCursorData {
3775 SourceLocation TokenBeginLoc;
3776 bool PointsAtMacroArgExpansion;
3777 bool VisitedObjCPropertyImplDecl;
3778 SourceLocation VisitedDeclaratorDeclStartLoc;
3779 CXCursor &BestCursor;
3780
3781 GetCursorData(SourceManager &SM,
3782 SourceLocation tokenBegin, CXCursor &outputCursor)
3783 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3784 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3785 VisitedObjCPropertyImplDecl = false;
3786 }
3787};
3788
3789static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3790 CXCursor parent,
3791 CXClientData client_data) {
3792 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3793 CXCursor *BestCursor = &Data->BestCursor;
3794
3795 // If we point inside a macro argument we should provide info of what the
3796 // token is so use the actual cursor, don't replace it with a macro expansion
3797 // cursor.
3798 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3799 return CXChildVisit_Recurse;
3800
3801 if (clang_isDeclaration(cursor.kind)) {
3802 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003803 if (const ObjCMethodDecl *MD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003804 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3805 if (MD->isImplicit())
3806 return CXChildVisit_Break;
3807
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003808 } else if (const ObjCInterfaceDecl *ID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003809 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3810 // Check that when we have multiple @class references in the same line,
3811 // that later ones do not override the previous ones.
3812 // If we have:
3813 // @class Foo, Bar;
3814 // source ranges for both start at '@', so 'Bar' will end up overriding
3815 // 'Foo' even though the cursor location was at 'Foo'.
3816 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3817 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003818 if (const ObjCInterfaceDecl *PrevID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003819 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3820 if (PrevID != ID &&
3821 !PrevID->isThisDeclarationADefinition() &&
3822 !ID->isThisDeclarationADefinition())
3823 return CXChildVisit_Break;
3824 }
3825
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003826 } else if (const DeclaratorDecl *DD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003827 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3828 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3829 // Check that when we have multiple declarators in the same line,
3830 // that later ones do not override the previous ones.
3831 // If we have:
3832 // int Foo, Bar;
3833 // source ranges for both start at 'int', so 'Bar' will end up overriding
3834 // 'Foo' even though the cursor location was at 'Foo'.
3835 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3836 return CXChildVisit_Break;
3837 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3838
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003839 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003840 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3841 (void)PropImp;
3842 // Check that when we have multiple @synthesize in the same line,
3843 // that later ones do not override the previous ones.
3844 // If we have:
3845 // @synthesize Foo, Bar;
3846 // source ranges for both start at '@', so 'Bar' will end up overriding
3847 // 'Foo' even though the cursor location was at 'Foo'.
3848 if (Data->VisitedObjCPropertyImplDecl)
3849 return CXChildVisit_Break;
3850 Data->VisitedObjCPropertyImplDecl = true;
3851 }
3852 }
3853
3854 if (clang_isExpression(cursor.kind) &&
3855 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003856 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003857 // Avoid having the cursor of an expression replace the declaration cursor
3858 // when the expression source range overlaps the declaration range.
3859 // This can happen for C++ constructor expressions whose range generally
3860 // include the variable declaration, e.g.:
3861 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3862 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3863 D->getLocation() == Data->TokenBeginLoc)
3864 return CXChildVisit_Break;
3865 }
3866 }
3867
3868 // If our current best cursor is the construction of a temporary object,
3869 // don't replace that cursor with a type reference, because we want
3870 // clang_getCursor() to point at the constructor.
3871 if (clang_isExpression(BestCursor->kind) &&
3872 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3873 cursor.kind == CXCursor_TypeRef) {
3874 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3875 // as having the actual point on the type reference.
3876 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3877 return CXChildVisit_Recurse;
3878 }
3879
3880 *BestCursor = cursor;
3881 return CXChildVisit_Recurse;
3882}
3883
3884CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3885 if (!TU)
3886 return clang_getNullCursor();
3887
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003888 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003889 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3890
3891 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3892 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3893
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003894 LOG_FUNC_SECTION {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003895 CXFile SearchFile;
3896 unsigned SearchLine, SearchColumn;
3897 CXFile ResultFile;
3898 unsigned ResultLine, ResultColumn;
3899 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3900 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3901 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3902
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003903 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3904 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003905 &ResultColumn, 0);
3906 SearchFileName = clang_getFileName(SearchFile);
3907 ResultFileName = clang_getFileName(ResultFile);
3908 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3909 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003910 *Log << llvm::format("(%s:%d:%d) = %s",
3911 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3912 clang_getCString(KindSpelling))
3913 << llvm::format("(%s:%d:%d):%s%s",
3914 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3915 clang_getCString(USR), IsDef);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003916 clang_disposeString(SearchFileName);
3917 clang_disposeString(ResultFileName);
3918 clang_disposeString(KindSpelling);
3919 clang_disposeString(USR);
3920
3921 CXCursor Definition = clang_getCursorDefinition(Result);
3922 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3923 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3924 CXString DefinitionKindSpelling
3925 = clang_getCursorKindSpelling(Definition.kind);
3926 CXFile DefinitionFile;
3927 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003928 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003929 &DefinitionLine, &DefinitionColumn, 0);
3930 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003931 *Log << llvm::format(" -> %s(%s:%d:%d)",
3932 clang_getCString(DefinitionKindSpelling),
3933 clang_getCString(DefinitionFileName),
3934 DefinitionLine, DefinitionColumn);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003935 clang_disposeString(DefinitionFileName);
3936 clang_disposeString(DefinitionKindSpelling);
3937 }
3938 }
3939
3940 return Result;
3941}
3942
3943CXCursor clang_getNullCursor(void) {
3944 return MakeCXCursorInvalid(CXCursor_InvalidFile);
3945}
3946
3947unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisd1d9df62013-01-08 18:23:28 +00003948 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
3949 // can't set consistently. For example, when visiting a DeclStmt we will set
3950 // it but we don't set it on the result of clang_getCursorDefinition for
3951 // a reference of the same declaration.
3952 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
3953 // when visiting a DeclStmt currently, the AST should be enhanced to be able
3954 // to provide that kind of info.
3955 if (clang_isDeclaration(X.kind))
3956 X.data[1] = 0;
3957 if (clang_isDeclaration(Y.kind))
3958 Y.data[1] = 0;
3959
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003960 return X == Y;
3961}
3962
3963unsigned clang_hashCursor(CXCursor C) {
3964 unsigned Index = 0;
3965 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3966 Index = 1;
3967
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003968 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003969 std::make_pair(C.kind, C.data[Index]));
3970}
3971
3972unsigned clang_isInvalid(enum CXCursorKind K) {
3973 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3974}
3975
3976unsigned clang_isDeclaration(enum CXCursorKind K) {
3977 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
3978 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
3979}
3980
3981unsigned clang_isReference(enum CXCursorKind K) {
3982 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3983}
3984
3985unsigned clang_isExpression(enum CXCursorKind K) {
3986 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3987}
3988
3989unsigned clang_isStatement(enum CXCursorKind K) {
3990 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3991}
3992
3993unsigned clang_isAttribute(enum CXCursorKind K) {
3994 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
3995}
3996
3997unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3998 return K == CXCursor_TranslationUnit;
3999}
4000
4001unsigned clang_isPreprocessing(enum CXCursorKind K) {
4002 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4003}
4004
4005unsigned clang_isUnexposed(enum CXCursorKind K) {
4006 switch (K) {
4007 case CXCursor_UnexposedDecl:
4008 case CXCursor_UnexposedExpr:
4009 case CXCursor_UnexposedStmt:
4010 case CXCursor_UnexposedAttr:
4011 return true;
4012 default:
4013 return false;
4014 }
4015}
4016
4017CXCursorKind clang_getCursorKind(CXCursor C) {
4018 return C.kind;
4019}
4020
4021CXSourceLocation clang_getCursorLocation(CXCursor C) {
4022 if (clang_isReference(C.kind)) {
4023 switch (C.kind) {
4024 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004025 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004026 = getCursorObjCSuperClassRef(C);
4027 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4028 }
4029
4030 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004031 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004032 = getCursorObjCProtocolRef(C);
4033 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4034 }
4035
4036 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004037 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004038 = getCursorObjCClassRef(C);
4039 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4040 }
4041
4042 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004043 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004044 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4045 }
4046
4047 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004048 std::pair<const TemplateDecl *, SourceLocation> P =
4049 getCursorTemplateRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004050 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4051 }
4052
4053 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004054 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004055 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4056 }
4057
4058 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004059 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004060 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4061 }
4062
4063 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004064 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004065 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4066 }
4067
4068 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004069 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004070 if (!BaseSpec)
4071 return clang_getNullLocation();
4072
4073 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4074 return cxloc::translateSourceLocation(getCursorContext(C),
4075 TSInfo->getTypeLoc().getBeginLoc());
4076
4077 return cxloc::translateSourceLocation(getCursorContext(C),
4078 BaseSpec->getLocStart());
4079 }
4080
4081 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004082 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004083 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4084 }
4085
4086 case CXCursor_OverloadedDeclRef:
4087 return cxloc::translateSourceLocation(getCursorContext(C),
4088 getCursorOverloadedDeclRef(C).second);
4089
4090 default:
4091 // FIXME: Need a way to enumerate all non-reference cases.
4092 llvm_unreachable("Missed a reference kind");
4093 }
4094 }
4095
4096 if (clang_isExpression(C.kind))
4097 return cxloc::translateSourceLocation(getCursorContext(C),
4098 getLocationFromExpr(getCursorExpr(C)));
4099
4100 if (clang_isStatement(C.kind))
4101 return cxloc::translateSourceLocation(getCursorContext(C),
4102 getCursorStmt(C)->getLocStart());
4103
4104 if (C.kind == CXCursor_PreprocessingDirective) {
4105 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4106 return cxloc::translateSourceLocation(getCursorContext(C), L);
4107 }
4108
4109 if (C.kind == CXCursor_MacroExpansion) {
4110 SourceLocation L
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004111 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004112 return cxloc::translateSourceLocation(getCursorContext(C), L);
4113 }
4114
4115 if (C.kind == CXCursor_MacroDefinition) {
4116 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4117 return cxloc::translateSourceLocation(getCursorContext(C), L);
4118 }
4119
4120 if (C.kind == CXCursor_InclusionDirective) {
4121 SourceLocation L
4122 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4123 return cxloc::translateSourceLocation(getCursorContext(C), L);
4124 }
4125
4126 if (!clang_isDeclaration(C.kind))
4127 return clang_getNullLocation();
4128
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004129 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004130 if (!D)
4131 return clang_getNullLocation();
4132
4133 SourceLocation Loc = D->getLocation();
4134 // FIXME: Multiple variables declared in a single declaration
4135 // currently lack the information needed to correctly determine their
4136 // ranges when accounting for the type-specifier. We use context
4137 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4138 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004139 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004140 if (!cxcursor::isFirstInDeclGroup(C))
4141 Loc = VD->getLocation();
4142 }
4143
4144 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004145 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004146 Loc = MD->getSelectorStartLoc();
4147
4148 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4149}
4150
4151} // end extern "C"
4152
4153CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4154 assert(TU);
4155
4156 // Guard against an invalid SourceLocation, or we may assert in one
4157 // of the following calls.
4158 if (SLoc.isInvalid())
4159 return clang_getNullCursor();
4160
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004161 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004162
4163 // Translate the given source location to make it point at the beginning of
4164 // the token under the cursor.
4165 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4166 CXXUnit->getASTContext().getLangOpts());
4167
4168 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4169 if (SLoc.isValid()) {
4170 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4171 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4172 /*VisitPreprocessorLast=*/true,
4173 /*VisitIncludedEntities=*/false,
4174 SourceLocation(SLoc));
4175 CursorVis.visitFileRegion();
4176 }
4177
4178 return Result;
4179}
4180
4181static SourceRange getRawCursorExtent(CXCursor C) {
4182 if (clang_isReference(C.kind)) {
4183 switch (C.kind) {
4184 case CXCursor_ObjCSuperClassRef:
4185 return getCursorObjCSuperClassRef(C).second;
4186
4187 case CXCursor_ObjCProtocolRef:
4188 return getCursorObjCProtocolRef(C).second;
4189
4190 case CXCursor_ObjCClassRef:
4191 return getCursorObjCClassRef(C).second;
4192
4193 case CXCursor_TypeRef:
4194 return getCursorTypeRef(C).second;
4195
4196 case CXCursor_TemplateRef:
4197 return getCursorTemplateRef(C).second;
4198
4199 case CXCursor_NamespaceRef:
4200 return getCursorNamespaceRef(C).second;
4201
4202 case CXCursor_MemberRef:
4203 return getCursorMemberRef(C).second;
4204
4205 case CXCursor_CXXBaseSpecifier:
4206 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4207
4208 case CXCursor_LabelRef:
4209 return getCursorLabelRef(C).second;
4210
4211 case CXCursor_OverloadedDeclRef:
4212 return getCursorOverloadedDeclRef(C).second;
4213
4214 case CXCursor_VariableRef:
4215 return getCursorVariableRef(C).second;
4216
4217 default:
4218 // FIXME: Need a way to enumerate all non-reference cases.
4219 llvm_unreachable("Missed a reference kind");
4220 }
4221 }
4222
4223 if (clang_isExpression(C.kind))
4224 return getCursorExpr(C)->getSourceRange();
4225
4226 if (clang_isStatement(C.kind))
4227 return getCursorStmt(C)->getSourceRange();
4228
4229 if (clang_isAttribute(C.kind))
4230 return getCursorAttr(C)->getRange();
4231
4232 if (C.kind == CXCursor_PreprocessingDirective)
4233 return cxcursor::getCursorPreprocessingDirective(C);
4234
4235 if (C.kind == CXCursor_MacroExpansion) {
4236 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004237 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004238 return TU->mapRangeFromPreamble(Range);
4239 }
4240
4241 if (C.kind == CXCursor_MacroDefinition) {
4242 ASTUnit *TU = getCursorASTUnit(C);
4243 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4244 return TU->mapRangeFromPreamble(Range);
4245 }
4246
4247 if (C.kind == CXCursor_InclusionDirective) {
4248 ASTUnit *TU = getCursorASTUnit(C);
4249 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4250 return TU->mapRangeFromPreamble(Range);
4251 }
4252
4253 if (C.kind == CXCursor_TranslationUnit) {
4254 ASTUnit *TU = getCursorASTUnit(C);
4255 FileID MainID = TU->getSourceManager().getMainFileID();
4256 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4257 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4258 return SourceRange(Start, End);
4259 }
4260
4261 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004262 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004263 if (!D)
4264 return SourceRange();
4265
4266 SourceRange R = D->getSourceRange();
4267 // FIXME: Multiple variables declared in a single declaration
4268 // currently lack the information needed to correctly determine their
4269 // ranges when accounting for the type-specifier. We use context
4270 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4271 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004272 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004273 if (!cxcursor::isFirstInDeclGroup(C))
4274 R.setBegin(VD->getLocation());
4275 }
4276 return R;
4277 }
4278 return SourceRange();
4279}
4280
4281/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4282/// the decl-specifier-seq for declarations.
4283static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4284 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004285 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004286 if (!D)
4287 return SourceRange();
4288
4289 SourceRange R = D->getSourceRange();
4290
4291 // Adjust the start of the location for declarations preceded by
4292 // declaration specifiers.
4293 SourceLocation StartLoc;
4294 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4295 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4296 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004297 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004298 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4299 StartLoc = TI->getTypeLoc().getLocStart();
4300 }
4301
4302 if (StartLoc.isValid() && R.getBegin().isValid() &&
4303 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4304 R.setBegin(StartLoc);
4305
4306 // FIXME: Multiple variables declared in a single declaration
4307 // currently lack the information needed to correctly determine their
4308 // ranges when accounting for the type-specifier. We use context
4309 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4310 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004311 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004312 if (!cxcursor::isFirstInDeclGroup(C))
4313 R.setBegin(VD->getLocation());
4314 }
4315
4316 return R;
4317 }
4318
4319 return getRawCursorExtent(C);
4320}
4321
4322extern "C" {
4323
4324CXSourceRange clang_getCursorExtent(CXCursor C) {
4325 SourceRange R = getRawCursorExtent(C);
4326 if (R.isInvalid())
4327 return clang_getNullRange();
4328
4329 return cxloc::translateSourceRange(getCursorContext(C), R);
4330}
4331
4332CXCursor clang_getCursorReferenced(CXCursor C) {
4333 if (clang_isInvalid(C.kind))
4334 return clang_getNullCursor();
4335
4336 CXTranslationUnit tu = getCursorTU(C);
4337 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004338 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004339 if (!D)
4340 return clang_getNullCursor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004341 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004342 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004343 if (const ObjCPropertyImplDecl *PropImpl =
4344 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004345 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4346 return MakeCXCursor(Property, tu);
4347
4348 return C;
4349 }
4350
4351 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004352 const Expr *E = getCursorExpr(C);
4353 const Decl *D = getDeclFromExpr(E);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004354 if (D) {
4355 CXCursor declCursor = MakeCXCursor(D, tu);
4356 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4357 declCursor);
4358 return declCursor;
4359 }
4360
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004361 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004362 return MakeCursorOverloadedDeclRef(Ovl, tu);
4363
4364 return clang_getNullCursor();
4365 }
4366
4367 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004368 const Stmt *S = getCursorStmt(C);
4369 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004370 if (LabelDecl *label = Goto->getLabel())
4371 if (LabelStmt *labelS = label->getStmt())
4372 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4373
4374 return clang_getNullCursor();
4375 }
4376
4377 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004378 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004379 return MakeMacroDefinitionCursor(Def, tu);
4380 }
4381
4382 if (!clang_isReference(C.kind))
4383 return clang_getNullCursor();
4384
4385 switch (C.kind) {
4386 case CXCursor_ObjCSuperClassRef:
4387 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4388
4389 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004390 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4391 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004392 return MakeCXCursor(Def, tu);
4393
4394 return MakeCXCursor(Prot, tu);
4395 }
4396
4397 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004398 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4399 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004400 return MakeCXCursor(Def, tu);
4401
4402 return MakeCXCursor(Class, tu);
4403 }
4404
4405 case CXCursor_TypeRef:
4406 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4407
4408 case CXCursor_TemplateRef:
4409 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4410
4411 case CXCursor_NamespaceRef:
4412 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4413
4414 case CXCursor_MemberRef:
4415 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4416
4417 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004418 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004419 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4420 tu ));
4421 }
4422
4423 case CXCursor_LabelRef:
4424 // FIXME: We end up faking the "parent" declaration here because we
4425 // don't want to make CXCursor larger.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004426 return MakeCXCursor(getCursorLabelRef(C).first,
4427 cxtu::getASTUnit(tu)->getASTContext()
4428 .getTranslationUnitDecl(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004429 tu);
4430
4431 case CXCursor_OverloadedDeclRef:
4432 return C;
4433
4434 case CXCursor_VariableRef:
4435 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4436
4437 default:
4438 // We would prefer to enumerate all non-reference cursor kinds here.
4439 llvm_unreachable("Unhandled reference cursor kind");
4440 }
4441}
4442
4443CXCursor clang_getCursorDefinition(CXCursor C) {
4444 if (clang_isInvalid(C.kind))
4445 return clang_getNullCursor();
4446
4447 CXTranslationUnit TU = getCursorTU(C);
4448
4449 bool WasReference = false;
4450 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4451 C = clang_getCursorReferenced(C);
4452 WasReference = true;
4453 }
4454
4455 if (C.kind == CXCursor_MacroExpansion)
4456 return clang_getCursorReferenced(C);
4457
4458 if (!clang_isDeclaration(C.kind))
4459 return clang_getNullCursor();
4460
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004461 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004462 if (!D)
4463 return clang_getNullCursor();
4464
4465 switch (D->getKind()) {
4466 // Declaration kinds that don't really separate the notions of
4467 // declaration and definition.
4468 case Decl::Namespace:
4469 case Decl::Typedef:
4470 case Decl::TypeAlias:
4471 case Decl::TypeAliasTemplate:
4472 case Decl::TemplateTypeParm:
4473 case Decl::EnumConstant:
4474 case Decl::Field:
John McCall76da55d2013-04-16 07:28:30 +00004475 case Decl::MSProperty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004476 case Decl::IndirectField:
4477 case Decl::ObjCIvar:
4478 case Decl::ObjCAtDefsField:
4479 case Decl::ImplicitParam:
4480 case Decl::ParmVar:
4481 case Decl::NonTypeTemplateParm:
4482 case Decl::TemplateTemplateParm:
4483 case Decl::ObjCCategoryImpl:
4484 case Decl::ObjCImplementation:
4485 case Decl::AccessSpec:
4486 case Decl::LinkageSpec:
4487 case Decl::ObjCPropertyImpl:
4488 case Decl::FileScopeAsm:
4489 case Decl::StaticAssert:
4490 case Decl::Block:
Tareq A. Siraj6afcf882013-04-16 19:37:38 +00004491 case Decl::Captured:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004492 case Decl::Label: // FIXME: Is this right??
4493 case Decl::ClassScopeFunctionSpecialization:
4494 case Decl::Import:
Alexey Bataevc6400582013-03-22 06:34:35 +00004495 case Decl::OMPThreadPrivate:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004496 return C;
4497
4498 // Declaration kinds that don't make any sense here, but are
4499 // nonetheless harmless.
David Blaikief23546a2013-02-22 17:44:58 +00004500 case Decl::Empty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004501 case Decl::TranslationUnit:
4502 break;
4503
4504 // Declaration kinds for which the definition is not resolvable.
4505 case Decl::UnresolvedUsingTypename:
4506 case Decl::UnresolvedUsingValue:
4507 break;
4508
4509 case Decl::UsingDirective:
4510 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4511 TU);
4512
4513 case Decl::NamespaceAlias:
4514 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4515
4516 case Decl::Enum:
4517 case Decl::Record:
4518 case Decl::CXXRecord:
4519 case Decl::ClassTemplateSpecialization:
4520 case Decl::ClassTemplatePartialSpecialization:
4521 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4522 return MakeCXCursor(Def, TU);
4523 return clang_getNullCursor();
4524
4525 case Decl::Function:
4526 case Decl::CXXMethod:
4527 case Decl::CXXConstructor:
4528 case Decl::CXXDestructor:
4529 case Decl::CXXConversion: {
4530 const FunctionDecl *Def = 0;
4531 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko05756dc2013-01-14 00:46:27 +00004532 return MakeCXCursor(Def, TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004533 return clang_getNullCursor();
4534 }
4535
4536 case Decl::Var: {
4537 // Ask the variable if it has a definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004538 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004539 return MakeCXCursor(Def, TU);
4540 return clang_getNullCursor();
4541 }
4542
4543 case Decl::FunctionTemplate: {
4544 const FunctionDecl *Def = 0;
4545 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4546 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4547 return clang_getNullCursor();
4548 }
4549
4550 case Decl::ClassTemplate: {
4551 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4552 ->getDefinition())
4553 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4554 TU);
4555 return clang_getNullCursor();
4556 }
4557
4558 case Decl::Using:
4559 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4560 D->getLocation(), TU);
4561
4562 case Decl::UsingShadow:
4563 return clang_getCursorDefinition(
4564 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4565 TU));
4566
4567 case Decl::ObjCMethod: {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004568 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004569 if (Method->isThisDeclarationADefinition())
4570 return C;
4571
4572 // Dig out the method definition in the associated
4573 // @implementation, if we have it.
4574 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004575 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004576 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4577 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4578 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4579 Method->isInstanceMethod()))
4580 if (Def->isThisDeclarationADefinition())
4581 return MakeCXCursor(Def, TU);
4582
4583 return clang_getNullCursor();
4584 }
4585
4586 case Decl::ObjCCategory:
4587 if (ObjCCategoryImplDecl *Impl
4588 = cast<ObjCCategoryDecl>(D)->getImplementation())
4589 return MakeCXCursor(Impl, TU);
4590 return clang_getNullCursor();
4591
4592 case Decl::ObjCProtocol:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004593 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004594 return MakeCXCursor(Def, TU);
4595 return clang_getNullCursor();
4596
4597 case Decl::ObjCInterface: {
4598 // There are two notions of a "definition" for an Objective-C
4599 // class: the interface and its implementation. When we resolved a
4600 // reference to an Objective-C class, produce the @interface as
4601 // the definition; when we were provided with the interface,
4602 // produce the @implementation as the definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004603 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004604 if (WasReference) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004605 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004606 return MakeCXCursor(Def, TU);
4607 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4608 return MakeCXCursor(Impl, TU);
4609 return clang_getNullCursor();
4610 }
4611
4612 case Decl::ObjCProperty:
4613 // FIXME: We don't really know where to find the
4614 // ObjCPropertyImplDecls that implement this property.
4615 return clang_getNullCursor();
4616
4617 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004618 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004619 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004620 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004621 return MakeCXCursor(Def, TU);
4622
4623 return clang_getNullCursor();
4624
4625 case Decl::Friend:
4626 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4627 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4628 return clang_getNullCursor();
4629
4630 case Decl::FriendTemplate:
4631 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4632 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4633 return clang_getNullCursor();
4634 }
4635
4636 return clang_getNullCursor();
4637}
4638
4639unsigned clang_isCursorDefinition(CXCursor C) {
4640 if (!clang_isDeclaration(C.kind))
4641 return 0;
4642
4643 return clang_getCursorDefinition(C) == C;
4644}
4645
4646CXCursor clang_getCanonicalCursor(CXCursor C) {
4647 if (!clang_isDeclaration(C.kind))
4648 return C;
4649
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004650 if (const Decl *D = getCursorDecl(C)) {
4651 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004652 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4653 return MakeCXCursor(CatD, getCursorTU(C));
4654
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004655 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4656 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004657 return MakeCXCursor(IFD, getCursorTU(C));
4658
4659 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4660 }
4661
4662 return C;
4663}
4664
4665int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4666 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4667}
4668
4669unsigned clang_getNumOverloadedDecls(CXCursor C) {
4670 if (C.kind != CXCursor_OverloadedDeclRef)
4671 return 0;
4672
4673 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004674 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004675 return E->getNumDecls();
4676
4677 if (OverloadedTemplateStorage *S
4678 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4679 return S->size();
4680
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004681 const Decl *D = Storage.get<const Decl *>();
4682 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004683 return Using->shadow_size();
4684
4685 return 0;
4686}
4687
4688CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4689 if (cursor.kind != CXCursor_OverloadedDeclRef)
4690 return clang_getNullCursor();
4691
4692 if (index >= clang_getNumOverloadedDecls(cursor))
4693 return clang_getNullCursor();
4694
4695 CXTranslationUnit TU = getCursorTU(cursor);
4696 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004697 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004698 return MakeCXCursor(E->decls_begin()[index], TU);
4699
4700 if (OverloadedTemplateStorage *S
4701 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4702 return MakeCXCursor(S->begin()[index], TU);
4703
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004704 const Decl *D = Storage.get<const Decl *>();
4705 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004706 // FIXME: This is, unfortunately, linear time.
4707 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4708 std::advance(Pos, index);
4709 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4710 }
4711
4712 return clang_getNullCursor();
4713}
4714
4715void clang_getDefinitionSpellingAndExtent(CXCursor C,
4716 const char **startBuf,
4717 const char **endBuf,
4718 unsigned *startLine,
4719 unsigned *startColumn,
4720 unsigned *endLine,
4721 unsigned *endColumn) {
4722 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004723 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004724 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4725
4726 SourceManager &SM = FD->getASTContext().getSourceManager();
4727 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4728 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4729 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4730 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4731 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4732 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4733}
4734
4735
4736CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4737 unsigned PieceIndex) {
4738 RefNamePieces Pieces;
4739
4740 switch (C.kind) {
4741 case CXCursor_MemberRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004742 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004743 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4744 E->getQualifierLoc().getSourceRange());
4745 break;
4746
4747 case CXCursor_DeclRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004748 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004749 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4750 E->getQualifierLoc().getSourceRange(),
4751 E->getOptionalExplicitTemplateArgs());
4752 break;
4753
4754 case CXCursor_CallExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004755 if (const CXXOperatorCallExpr *OCE =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004756 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004757 const Expr *Callee = OCE->getCallee();
4758 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004759 Callee = ICE->getSubExpr();
4760
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004761 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004762 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4763 DRE->getQualifierLoc().getSourceRange());
4764 }
4765 break;
4766
4767 default:
4768 break;
4769 }
4770
4771 if (Pieces.empty()) {
4772 if (PieceIndex == 0)
4773 return clang_getCursorExtent(C);
4774 } else if (PieceIndex < Pieces.size()) {
4775 SourceRange R = Pieces[PieceIndex];
4776 if (R.isValid())
4777 return cxloc::translateSourceRange(getCursorContext(C), R);
4778 }
4779
4780 return clang_getNullRange();
4781}
4782
4783void clang_enableStackTraces(void) {
4784 llvm::sys::PrintStackTraceOnErrorSignal();
4785}
4786
4787void clang_executeOnThread(void (*fn)(void*), void *user_data,
4788 unsigned stack_size) {
4789 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4790}
4791
4792} // end: extern "C"
4793
4794//===----------------------------------------------------------------------===//
4795// Token-based Operations.
4796//===----------------------------------------------------------------------===//
4797
4798/* CXToken layout:
4799 * int_data[0]: a CXTokenKind
4800 * int_data[1]: starting token location
4801 * int_data[2]: token length
4802 * int_data[3]: reserved
4803 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4804 * otherwise unused.
4805 */
4806extern "C" {
4807
4808CXTokenKind clang_getTokenKind(CXToken CXTok) {
4809 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4810}
4811
4812CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4813 switch (clang_getTokenKind(CXTok)) {
4814 case CXToken_Identifier:
4815 case CXToken_Keyword:
4816 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00004817 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004818 ->getNameStart());
4819
4820 case CXToken_Literal: {
4821 // We have stashed the starting pointer in the ptr_data field. Use it.
4822 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004823 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004824 }
4825
4826 case CXToken_Punctuation:
4827 case CXToken_Comment:
4828 break;
4829 }
4830
4831 // We have to find the starting buffer pointer the hard way, by
4832 // deconstructing the source location.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004833 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004834 if (!CXXUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004835 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004836
4837 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4838 std::pair<FileID, unsigned> LocInfo
4839 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4840 bool Invalid = false;
4841 StringRef Buffer
4842 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4843 if (Invalid)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004844 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004845
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004846 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004847}
4848
4849CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004850 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004851 if (!CXXUnit)
4852 return clang_getNullLocation();
4853
4854 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4855 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4856}
4857
4858CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004859 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004860 if (!CXXUnit)
4861 return clang_getNullRange();
4862
4863 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4864 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4865}
4866
4867static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4868 SmallVectorImpl<CXToken> &CXTokens) {
4869 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4870 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004871 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004872 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004873 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004874
4875 // Cannot tokenize across files.
4876 if (BeginLocInfo.first != EndLocInfo.first)
4877 return;
4878
4879 // Create a lexer
4880 bool Invalid = false;
4881 StringRef Buffer
4882 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4883 if (Invalid)
4884 return;
4885
4886 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4887 CXXUnit->getASTContext().getLangOpts(),
4888 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4889 Lex.SetCommentRetentionState(true);
4890
4891 // Lex tokens until we hit the end of the range.
4892 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4893 Token Tok;
4894 bool previousWasAt = false;
4895 do {
4896 // Lex the next token
4897 Lex.LexFromRawLexer(Tok);
4898 if (Tok.is(tok::eof))
4899 break;
4900
4901 // Initialize the CXToken.
4902 CXToken CXTok;
4903
4904 // - Common fields
4905 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4906 CXTok.int_data[2] = Tok.getLength();
4907 CXTok.int_data[3] = 0;
4908
4909 // - Kind-specific fields
4910 if (Tok.isLiteral()) {
4911 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00004912 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004913 } else if (Tok.is(tok::raw_identifier)) {
4914 // Lookup the identifier to determine whether we have a keyword.
4915 IdentifierInfo *II
4916 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4917
4918 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4919 CXTok.int_data[0] = CXToken_Keyword;
4920 }
4921 else {
4922 CXTok.int_data[0] = Tok.is(tok::identifier)
4923 ? CXToken_Identifier
4924 : CXToken_Keyword;
4925 }
4926 CXTok.ptr_data = II;
4927 } else if (Tok.is(tok::comment)) {
4928 CXTok.int_data[0] = CXToken_Comment;
4929 CXTok.ptr_data = 0;
4930 } else {
4931 CXTok.int_data[0] = CXToken_Punctuation;
4932 CXTok.ptr_data = 0;
4933 }
4934 CXTokens.push_back(CXTok);
4935 previousWasAt = Tok.is(tok::at);
4936 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
4937}
4938
4939void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4940 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00004941 LOG_FUNC_SECTION {
4942 *Log << TU << ' ' << Range;
4943 }
4944
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004945 if (Tokens)
4946 *Tokens = 0;
4947 if (NumTokens)
4948 *NumTokens = 0;
4949
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00004950 if (!TU)
4951 return;
4952
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004953 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004954 if (!CXXUnit || !Tokens || !NumTokens)
4955 return;
4956
4957 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4958
4959 SourceRange R = cxloc::translateCXSourceRange(Range);
4960 if (R.isInvalid())
4961 return;
4962
4963 SmallVector<CXToken, 32> CXTokens;
4964 getTokens(CXXUnit, R, CXTokens);
4965
4966 if (CXTokens.empty())
4967 return;
4968
4969 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4970 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4971 *NumTokens = CXTokens.size();
4972}
4973
4974void clang_disposeTokens(CXTranslationUnit TU,
4975 CXToken *Tokens, unsigned NumTokens) {
4976 free(Tokens);
4977}
4978
4979} // end: extern "C"
4980
4981//===----------------------------------------------------------------------===//
4982// Token annotation APIs.
4983//===----------------------------------------------------------------------===//
4984
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004985static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4986 CXCursor parent,
4987 CXClientData client_data);
4988static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
4989 CXClientData client_data);
4990
4991namespace {
4992class AnnotateTokensWorker {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004993 CXToken *Tokens;
4994 CXCursor *Cursors;
4995 unsigned NumTokens;
4996 unsigned TokIdx;
4997 unsigned PreprocessingTokIdx;
4998 CursorVisitor AnnotateVis;
4999 SourceManager &SrcMgr;
5000 bool HasContextSensitiveKeywords;
5001
5002 struct PostChildrenInfo {
5003 CXCursor Cursor;
5004 SourceRange CursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005005 unsigned BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005006 unsigned BeforeChildrenTokenIdx;
5007 };
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00005008 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005009
5010 bool MoreTokens() const { return TokIdx < NumTokens; }
5011 unsigned NextToken() const { return TokIdx; }
5012 void AdvanceToken() { ++TokIdx; }
5013 SourceLocation GetTokenLoc(unsigned tokI) {
5014 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5015 }
5016 bool isFunctionMacroToken(unsigned tokI) const {
5017 return Tokens[tokI].int_data[3] != 0;
5018 }
5019 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
5020 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
5021 }
5022
5023 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005024 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005025 SourceRange);
5026
5027public:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005028 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005029 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005030 : Tokens(tokens), Cursors(cursors),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005031 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005032 AnnotateVis(TU,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005033 AnnotateTokensVisitor, this,
5034 /*VisitPreprocessorLast=*/true,
5035 /*VisitIncludedEntities=*/false,
5036 RegionOfInterest,
5037 /*VisitDeclsOnly=*/false,
5038 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005039 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005040 HasContextSensitiveKeywords(false) { }
5041
5042 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5043 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5044 bool postVisitChildren(CXCursor cursor);
5045 void AnnotateTokens();
5046
5047 /// \brief Determine whether the annotator saw any cursors that have
5048 /// context-sensitive keywords.
5049 bool hasContextSensitiveKeywords() const {
5050 return HasContextSensitiveKeywords;
5051 }
5052
5053 ~AnnotateTokensWorker() {
5054 assert(PostChildrenInfos.empty());
5055 }
5056};
5057}
5058
5059void AnnotateTokensWorker::AnnotateTokens() {
5060 // Walk the AST within the region of interest, annotating tokens
5061 // along the way.
5062 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005063}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005064
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005065static inline void updateCursorAnnotation(CXCursor &Cursor,
5066 const CXCursor &updateC) {
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005067 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005068 return;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005069 Cursor = updateC;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005070}
5071
5072/// \brief It annotates and advances tokens with a cursor until the comparison
5073//// between the cursor location and the source range is the same as
5074/// \arg compResult.
5075///
5076/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5077/// Pass RangeOverlap to annotate tokens inside a range.
5078void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5079 RangeComparisonResult compResult,
5080 SourceRange range) {
5081 while (MoreTokens()) {
5082 const unsigned I = NextToken();
5083 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005084 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5085 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005086
5087 SourceLocation TokLoc = GetTokenLoc(I);
5088 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005089 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005090 AdvanceToken();
5091 continue;
5092 }
5093 break;
5094 }
5095}
5096
5097/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005098/// \returns true if it advanced beyond all macro tokens, false otherwise.
5099bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005100 CXCursor updateC,
5101 RangeComparisonResult compResult,
5102 SourceRange range) {
5103 assert(MoreTokens());
5104 assert(isFunctionMacroToken(NextToken()) &&
5105 "Should be called only for macro arg tokens");
5106
5107 // This works differently than annotateAndAdvanceTokens; because expanded
5108 // macro arguments can have arbitrary translation-unit source order, we do not
5109 // advance the token index one by one until a token fails the range test.
5110 // We only advance once past all of the macro arg tokens if all of them
5111 // pass the range test. If one of them fails we keep the token index pointing
5112 // at the start of the macro arg tokens so that the failing token will be
5113 // annotated by a subsequent annotation try.
5114
5115 bool atLeastOneCompFail = false;
5116
5117 unsigned I = NextToken();
5118 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5119 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5120 if (TokLoc.isFileID())
5121 continue; // not macro arg token, it's parens or comma.
5122 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5123 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5124 Cursors[I] = updateC;
5125 } else
5126 atLeastOneCompFail = true;
5127 }
5128
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005129 if (atLeastOneCompFail)
5130 return false;
5131
5132 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5133 return true;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005134}
5135
5136enum CXChildVisitResult
5137AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005138 SourceRange cursorRange = getRawCursorExtent(cursor);
5139 if (cursorRange.isInvalid())
5140 return CXChildVisit_Recurse;
5141
5142 if (!HasContextSensitiveKeywords) {
5143 // Objective-C properties can have context-sensitive keywords.
5144 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005145 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005146 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5147 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5148 }
5149 // Objective-C methods can have context-sensitive keywords.
5150 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5151 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005152 if (const ObjCMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005153 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5154 if (Method->getObjCDeclQualifier())
5155 HasContextSensitiveKeywords = true;
5156 else {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005157 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5158 PEnd = Method->param_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005159 P != PEnd; ++P) {
5160 if ((*P)->getObjCDeclQualifier()) {
5161 HasContextSensitiveKeywords = true;
5162 break;
5163 }
5164 }
5165 }
5166 }
5167 }
5168 // C++ methods can have context-sensitive keywords.
5169 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005170 if (const CXXMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005171 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5172 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5173 HasContextSensitiveKeywords = true;
5174 }
5175 }
5176 // C++ classes can have context-sensitive keywords.
5177 else if (cursor.kind == CXCursor_StructDecl ||
5178 cursor.kind == CXCursor_ClassDecl ||
5179 cursor.kind == CXCursor_ClassTemplate ||
5180 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005181 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005182 if (D->hasAttr<FinalAttr>())
5183 HasContextSensitiveKeywords = true;
5184 }
5185 }
Argyrios Kyrtzidis25cd4a22013-06-04 18:24:30 +00005186
5187 // Don't override a property annotation with its getter/setter method.
5188 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5189 parent.kind == CXCursor_ObjCPropertyDecl)
5190 return CXChildVisit_Continue;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005191
5192 if (clang_isPreprocessing(cursor.kind)) {
5193 // Items in the preprocessing record are kept separate from items in
5194 // declarations, so we keep a separate token index.
5195 unsigned SavedTokIdx = TokIdx;
5196 TokIdx = PreprocessingTokIdx;
5197
5198 // Skip tokens up until we catch up to the beginning of the preprocessing
5199 // entry.
5200 while (MoreTokens()) {
5201 const unsigned I = NextToken();
5202 SourceLocation TokLoc = GetTokenLoc(I);
5203 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5204 case RangeBefore:
5205 AdvanceToken();
5206 continue;
5207 case RangeAfter:
5208 case RangeOverlap:
5209 break;
5210 }
5211 break;
5212 }
5213
5214 // Look at all of the tokens within this range.
5215 while (MoreTokens()) {
5216 const unsigned I = NextToken();
5217 SourceLocation TokLoc = GetTokenLoc(I);
5218 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5219 case RangeBefore:
5220 llvm_unreachable("Infeasible");
5221 case RangeAfter:
5222 break;
5223 case RangeOverlap:
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005224 // For macro expansions, just note where the beginning of the macro
5225 // expansion occurs.
5226 if (cursor.kind == CXCursor_MacroExpansion) {
5227 if (TokLoc == cursorRange.getBegin())
5228 Cursors[I] = cursor;
5229 AdvanceToken();
5230 break;
5231 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005232 // We may have already annotated macro names inside macro definitions.
5233 if (Cursors[I].kind != CXCursor_MacroExpansion)
5234 Cursors[I] = cursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005235 AdvanceToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005236 continue;
5237 }
5238 break;
5239 }
5240
5241 // Save the preprocessing token index; restore the non-preprocessing
5242 // token index.
5243 PreprocessingTokIdx = TokIdx;
5244 TokIdx = SavedTokIdx;
5245 return CXChildVisit_Recurse;
5246 }
5247
5248 if (cursorRange.isInvalid())
5249 return CXChildVisit_Continue;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005250
5251 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005252 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005253 const enum CXCursorKind K = clang_getCursorKind(parent);
5254 const CXCursor updateC =
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005255 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5256 // Attributes are annotated out-of-order, skip tokens until we reach it.
5257 clang_isAttribute(cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005258 ? clang_getNullCursor() : parent;
5259
5260 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5261
5262 // Avoid having the cursor of an expression "overwrite" the annotation of the
5263 // variable declaration that it belongs to.
5264 // This can happen for C++ constructor expressions whose range generally
5265 // include the variable declaration, e.g.:
5266 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5267 if (clang_isExpression(cursorK)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00005268 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenko404628c2013-01-26 18:12:08 +00005269 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005270 const unsigned I = NextToken();
5271 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5272 E->getLocStart() == D->getLocation() &&
5273 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005274 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005275 AdvanceToken();
5276 }
5277 }
5278 }
5279
5280 // Before recursing into the children keep some state that we are going
5281 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5282 // extra work after the child nodes are visited.
5283 // Note that we don't call VisitChildren here to avoid traversing statements
5284 // code-recursively which can blow the stack.
5285
5286 PostChildrenInfo Info;
5287 Info.Cursor = cursor;
5288 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005289 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005290 Info.BeforeChildrenTokenIdx = NextToken();
5291 PostChildrenInfos.push_back(Info);
5292
5293 return CXChildVisit_Recurse;
5294}
5295
5296bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5297 if (PostChildrenInfos.empty())
5298 return false;
5299 const PostChildrenInfo &Info = PostChildrenInfos.back();
5300 if (!clang_equalCursors(Info.Cursor, cursor))
5301 return false;
5302
5303 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5304 const unsigned AfterChildren = NextToken();
5305 SourceRange cursorRange = Info.CursorRange;
5306
5307 // Scan the tokens that are at the end of the cursor, but are not captured
5308 // but the child cursors.
5309 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5310
5311 // Scan the tokens that are at the beginning of the cursor, but are not
5312 // capture by the child cursors.
5313 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5314 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5315 break;
5316
5317 Cursors[I] = cursor;
5318 }
5319
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005320 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5321 // encountered the attribute cursor.
5322 if (clang_isAttribute(cursor.kind))
5323 TokIdx = Info.BeforeReachingCursorIdx;
5324
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005325 PostChildrenInfos.pop_back();
5326 return false;
5327}
5328
5329static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5330 CXCursor parent,
5331 CXClientData client_data) {
5332 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5333}
5334
5335static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5336 CXClientData client_data) {
5337 return static_cast<AnnotateTokensWorker*>(client_data)->
5338 postVisitChildren(cursor);
5339}
5340
5341namespace {
5342
5343/// \brief Uses the macro expansions in the preprocessing record to find
5344/// and mark tokens that are macro arguments. This info is used by the
5345/// AnnotateTokensWorker.
5346class MarkMacroArgTokensVisitor {
5347 SourceManager &SM;
5348 CXToken *Tokens;
5349 unsigned NumTokens;
5350 unsigned CurIdx;
5351
5352public:
5353 MarkMacroArgTokensVisitor(SourceManager &SM,
5354 CXToken *tokens, unsigned numTokens)
5355 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5356
5357 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5358 if (cursor.kind != CXCursor_MacroExpansion)
5359 return CXChildVisit_Continue;
5360
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00005361 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005362 if (macroRange.getBegin() == macroRange.getEnd())
5363 return CXChildVisit_Continue; // it's not a function macro.
5364
5365 for (; CurIdx < NumTokens; ++CurIdx) {
5366 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5367 macroRange.getBegin()))
5368 break;
5369 }
5370
5371 if (CurIdx == NumTokens)
5372 return CXChildVisit_Break;
5373
5374 for (; CurIdx < NumTokens; ++CurIdx) {
5375 SourceLocation tokLoc = getTokenLoc(CurIdx);
5376 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5377 break;
5378
5379 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5380 }
5381
5382 if (CurIdx == NumTokens)
5383 return CXChildVisit_Break;
5384
5385 return CXChildVisit_Continue;
5386 }
5387
5388private:
5389 SourceLocation getTokenLoc(unsigned tokI) {
5390 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5391 }
5392
5393 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5394 // The third field is reserved and currently not used. Use it here
5395 // to mark macro arg expanded tokens with their expanded locations.
5396 Tokens[tokI].int_data[3] = loc.getRawEncoding();
5397 }
5398};
5399
5400} // end anonymous namespace
5401
5402static CXChildVisitResult
5403MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5404 CXClientData client_data) {
5405 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5406 parent);
5407}
5408
5409namespace {
5410 struct clang_annotateTokens_Data {
5411 CXTranslationUnit TU;
5412 ASTUnit *CXXUnit;
5413 CXToken *Tokens;
5414 unsigned NumTokens;
5415 CXCursor *Cursors;
5416 };
5417}
5418
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005419/// \brief Used by \c annotatePreprocessorTokens.
5420/// \returns true if lexing was finished, false otherwise.
5421static bool lexNext(Lexer &Lex, Token &Tok,
5422 unsigned &NextIdx, unsigned NumTokens) {
5423 if (NextIdx >= NumTokens)
5424 return true;
5425
5426 ++NextIdx;
5427 Lex.LexFromRawLexer(Tok);
5428 if (Tok.is(tok::eof))
5429 return true;
5430
5431 return false;
5432}
5433
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005434static void annotatePreprocessorTokens(CXTranslationUnit TU,
5435 SourceRange RegionOfInterest,
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005436 CXCursor *Cursors,
5437 CXToken *Tokens,
5438 unsigned NumTokens) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005439 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005440
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005441 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005442 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5443 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005444 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005445 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005446 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005447
5448 if (BeginLocInfo.first != EndLocInfo.first)
5449 return;
5450
5451 StringRef Buffer;
5452 bool Invalid = false;
5453 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5454 if (Buffer.empty() || Invalid)
5455 return;
5456
5457 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5458 CXXUnit->getASTContext().getLangOpts(),
5459 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5460 Buffer.end());
5461 Lex.SetCommentRetentionState(true);
5462
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005463 unsigned NextIdx = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005464 // Lex tokens in raw mode until we hit the end of the range, to avoid
5465 // entering #includes or expanding macros.
5466 while (true) {
5467 Token Tok;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005468 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5469 break;
5470 unsigned TokIdx = NextIdx-1;
5471 assert(Tok.getLocation() ==
5472 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005473
5474 reprocess:
5475 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005476 // We have found a preprocessing directive. Annotate the tokens
5477 // appropriately.
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005478 //
5479 // FIXME: Some simple tests here could identify macro definitions and
5480 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005481
5482 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005483 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5484 break;
5485
5486 MacroInfo *MI = 0;
5487 if (Tok.is(tok::raw_identifier) &&
5488 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5489 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5490 break;
5491
5492 if (Tok.is(tok::raw_identifier)) {
5493 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5494 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5495 SourceLocation MappedTokLoc =
5496 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5497 MI = getMacroInfo(II, MappedTokLoc, TU);
5498 }
5499 }
5500
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005501 bool finished = false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005502 do {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005503 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5504 finished = true;
5505 break;
5506 }
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005507 // If we are in a macro definition, check if the token was ever a
5508 // macro name and annotate it if that's the case.
5509 if (MI) {
5510 SourceLocation SaveLoc = Tok.getLocation();
5511 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5512 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5513 Tok.setLocation(SaveLoc);
5514 if (MacroDef)
5515 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5516 Tok.getLocation(), TU);
5517 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005518 } while (!Tok.isAtStartOfLine());
5519
5520 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5521 assert(TokIdx <= LastIdx);
5522 SourceLocation EndLoc =
5523 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5524 CXCursor Cursor =
5525 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5526
5527 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005528 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005529
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005530 if (finished)
5531 break;
5532 goto reprocess;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005533 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005534 }
5535}
5536
5537// This gets run a separate thread to avoid stack blowout.
5538static void clang_annotateTokensImpl(void *UserData) {
5539 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5540 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5541 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5542 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5543 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5544
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00005545 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005546 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5547 setThreadBackgroundPriority();
5548
5549 // Determine the region of interest, which contains all of the tokens.
5550 SourceRange RegionOfInterest;
5551 RegionOfInterest.setBegin(
5552 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5553 RegionOfInterest.setEnd(
5554 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5555 Tokens[NumTokens-1])));
5556
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005557 // Relex the tokens within the source range to look for preprocessing
5558 // directives.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005559 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005560
5561 // If begin location points inside a macro argument, set it to the expansion
5562 // location so we can have the full context when annotating semantically.
5563 {
5564 SourceManager &SM = CXXUnit->getSourceManager();
5565 SourceLocation Loc =
5566 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5567 if (Loc.isMacroID())
5568 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5569 }
5570
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005571 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5572 // Search and mark tokens that are macro argument expansions.
5573 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5574 Tokens, NumTokens);
5575 CursorVisitor MacroArgMarker(TU,
5576 MarkMacroArgTokensVisitorDelegate, &Visitor,
5577 /*VisitPreprocessorLast=*/true,
5578 /*VisitIncludedEntities=*/false,
5579 RegionOfInterest);
5580 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5581 }
5582
5583 // Annotate all of the source locations in the region of interest that map to
5584 // a specific cursor.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005585 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005586
5587 // FIXME: We use a ridiculous stack size here because the data-recursion
5588 // algorithm uses a large stack frame than the non-data recursive version,
5589 // and AnnotationTokensWorker currently transforms the data-recursion
5590 // algorithm back into a traditional recursion by explicitly calling
5591 // VisitChildren(). We will need to remove this explicit recursive call.
5592 W.AnnotateTokens();
5593
5594 // If we ran into any entities that involve context-sensitive keywords,
5595 // take another pass through the tokens to mark them as such.
5596 if (W.hasContextSensitiveKeywords()) {
5597 for (unsigned I = 0; I != NumTokens; ++I) {
5598 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5599 continue;
5600
5601 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5602 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005603 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005604 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5605 if (Property->getPropertyAttributesAsWritten() != 0 &&
5606 llvm::StringSwitch<bool>(II->getName())
5607 .Case("readonly", true)
5608 .Case("assign", true)
5609 .Case("unsafe_unretained", true)
5610 .Case("readwrite", true)
5611 .Case("retain", true)
5612 .Case("copy", true)
5613 .Case("nonatomic", true)
5614 .Case("atomic", true)
5615 .Case("getter", true)
5616 .Case("setter", true)
5617 .Case("strong", true)
5618 .Case("weak", true)
5619 .Default(false))
5620 Tokens[I].int_data[0] = CXToken_Keyword;
5621 }
5622 continue;
5623 }
5624
5625 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5626 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5627 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5628 if (llvm::StringSwitch<bool>(II->getName())
5629 .Case("in", true)
5630 .Case("out", true)
5631 .Case("inout", true)
5632 .Case("oneway", true)
5633 .Case("bycopy", true)
5634 .Case("byref", true)
5635 .Default(false))
5636 Tokens[I].int_data[0] = CXToken_Keyword;
5637 continue;
5638 }
5639
5640 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5641 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5642 Tokens[I].int_data[0] = CXToken_Keyword;
5643 continue;
5644 }
5645 }
5646 }
5647}
5648
5649extern "C" {
5650
5651void clang_annotateTokens(CXTranslationUnit TU,
5652 CXToken *Tokens, unsigned NumTokens,
5653 CXCursor *Cursors) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00005654 if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005655 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005656 return;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005657 }
5658
5659 LOG_FUNC_SECTION {
5660 *Log << TU << ' ';
5661 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5662 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5663 *Log << clang_getRange(bloc, eloc);
5664 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005665
5666 // Any token we don't specifically annotate will have a NULL cursor.
5667 CXCursor C = clang_getNullCursor();
5668 for (unsigned I = 0; I != NumTokens; ++I)
5669 Cursors[I] = C;
5670
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005671 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005672 if (!CXXUnit)
5673 return;
5674
5675 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5676
5677 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5678 llvm::CrashRecoveryContext CRC;
5679 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5680 GetSafetyThreadStackSize() * 2)) {
5681 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5682 }
5683}
5684
5685} // end: extern "C"
5686
5687//===----------------------------------------------------------------------===//
5688// Operations for querying linkage of a cursor.
5689//===----------------------------------------------------------------------===//
5690
5691extern "C" {
5692CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5693 if (!clang_isDeclaration(cursor.kind))
5694 return CXLinkage_Invalid;
5695
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005696 const Decl *D = cxcursor::getCursorDecl(cursor);
5697 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola181e3ec2013-05-13 00:12:11 +00005698 switch (ND->getLinkageInternal()) {
Rafael Espindolaa99ecbc2013-05-25 17:16:20 +00005699 case NoLinkage:
5700 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005701 case InternalLinkage: return CXLinkage_Internal;
5702 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5703 case ExternalLinkage: return CXLinkage_External;
5704 };
5705
5706 return CXLinkage_Invalid;
5707}
5708} // end: extern "C"
5709
5710//===----------------------------------------------------------------------===//
5711// Operations for querying language of a cursor.
5712//===----------------------------------------------------------------------===//
5713
5714static CXLanguageKind getDeclLanguage(const Decl *D) {
5715 if (!D)
5716 return CXLanguage_C;
5717
5718 switch (D->getKind()) {
5719 default:
5720 break;
5721 case Decl::ImplicitParam:
5722 case Decl::ObjCAtDefsField:
5723 case Decl::ObjCCategory:
5724 case Decl::ObjCCategoryImpl:
5725 case Decl::ObjCCompatibleAlias:
5726 case Decl::ObjCImplementation:
5727 case Decl::ObjCInterface:
5728 case Decl::ObjCIvar:
5729 case Decl::ObjCMethod:
5730 case Decl::ObjCProperty:
5731 case Decl::ObjCPropertyImpl:
5732 case Decl::ObjCProtocol:
5733 return CXLanguage_ObjC;
5734 case Decl::CXXConstructor:
5735 case Decl::CXXConversion:
5736 case Decl::CXXDestructor:
5737 case Decl::CXXMethod:
5738 case Decl::CXXRecord:
5739 case Decl::ClassTemplate:
5740 case Decl::ClassTemplatePartialSpecialization:
5741 case Decl::ClassTemplateSpecialization:
5742 case Decl::Friend:
5743 case Decl::FriendTemplate:
5744 case Decl::FunctionTemplate:
5745 case Decl::LinkageSpec:
5746 case Decl::Namespace:
5747 case Decl::NamespaceAlias:
5748 case Decl::NonTypeTemplateParm:
5749 case Decl::StaticAssert:
5750 case Decl::TemplateTemplateParm:
5751 case Decl::TemplateTypeParm:
5752 case Decl::UnresolvedUsingTypename:
5753 case Decl::UnresolvedUsingValue:
5754 case Decl::Using:
5755 case Decl::UsingDirective:
5756 case Decl::UsingShadow:
5757 return CXLanguage_CPlusPlus;
5758 }
5759
5760 return CXLanguage_C;
5761}
5762
5763extern "C" {
5764
5765enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5766 if (clang_isDeclaration(cursor.kind))
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005767 if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005768 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5769 return CXAvailability_Available;
5770
5771 switch (D->getAvailability()) {
5772 case AR_Available:
5773 case AR_NotYetIntroduced:
5774 return CXAvailability_Available;
5775
5776 case AR_Deprecated:
5777 return CXAvailability_Deprecated;
5778
5779 case AR_Unavailable:
5780 return CXAvailability_NotAvailable;
5781 }
5782 }
5783
5784 return CXAvailability_Available;
5785}
5786
5787static CXVersion convertVersion(VersionTuple In) {
5788 CXVersion Out = { -1, -1, -1 };
5789 if (In.empty())
5790 return Out;
5791
5792 Out.Major = In.getMajor();
5793
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005794 Optional<unsigned> Minor = In.getMinor();
5795 if (Minor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005796 Out.Minor = *Minor;
5797 else
5798 return Out;
5799
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005800 Optional<unsigned> Subminor = In.getSubminor();
5801 if (Subminor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005802 Out.Subminor = *Subminor;
5803
5804 return Out;
5805}
5806
5807int clang_getCursorPlatformAvailability(CXCursor cursor,
5808 int *always_deprecated,
5809 CXString *deprecated_message,
5810 int *always_unavailable,
5811 CXString *unavailable_message,
5812 CXPlatformAvailability *availability,
5813 int availability_size) {
5814 if (always_deprecated)
5815 *always_deprecated = 0;
5816 if (deprecated_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005817 *deprecated_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005818 if (always_unavailable)
5819 *always_unavailable = 0;
5820 if (unavailable_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005821 *unavailable_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005822
5823 if (!clang_isDeclaration(cursor.kind))
5824 return 0;
5825
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005826 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005827 if (!D)
5828 return 0;
5829
5830 int N = 0;
5831 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5832 ++A) {
5833 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5834 if (always_deprecated)
5835 *always_deprecated = 1;
5836 if (deprecated_message)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005837 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005838 continue;
5839 }
5840
5841 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5842 if (always_unavailable)
5843 *always_unavailable = 1;
5844 if (unavailable_message) {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005845 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005846 }
5847 continue;
5848 }
5849
5850 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5851 if (N < availability_size) {
5852 availability[N].Platform
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005853 = cxstring::createDup(Avail->getPlatform()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005854 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5855 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5856 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5857 availability[N].Unavailable = Avail->getUnavailable();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005858 availability[N].Message = cxstring::createDup(Avail->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005859 }
5860 ++N;
5861 }
5862 }
5863
5864 return N;
5865}
5866
5867void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5868 clang_disposeString(availability->Platform);
5869 clang_disposeString(availability->Message);
5870}
5871
5872CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5873 if (clang_isDeclaration(cursor.kind))
5874 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5875
5876 return CXLanguage_Invalid;
5877}
5878
5879 /// \brief If the given cursor is the "templated" declaration
5880 /// descibing a class or function template, return the class or
5881 /// function template.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005882static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005883 if (!D)
5884 return 0;
5885
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005886 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005887 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
5888 return FunTmpl;
5889
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005890 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005891 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
5892 return ClassTmpl;
5893
5894 return D;
5895}
5896
5897CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
5898 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005899 if (const Decl *D = getCursorDecl(cursor)) {
5900 const DeclContext *DC = D->getDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005901 if (!DC)
5902 return clang_getNullCursor();
5903
5904 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5905 getCursorTU(cursor));
5906 }
5907 }
5908
5909 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005910 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005911 return MakeCXCursor(D, getCursorTU(cursor));
5912 }
5913
5914 return clang_getNullCursor();
5915}
5916
5917CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5918 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005919 if (const Decl *D = getCursorDecl(cursor)) {
5920 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005921 if (!DC)
5922 return clang_getNullCursor();
5923
5924 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5925 getCursorTU(cursor));
5926 }
5927 }
5928
5929 // FIXME: Note that we can't easily compute the lexical context of a
5930 // statement or expression, so we return nothing.
5931 return clang_getNullCursor();
5932}
5933
5934CXFile clang_getIncludedFile(CXCursor cursor) {
5935 if (cursor.kind != CXCursor_InclusionDirective)
5936 return 0;
5937
Dmitri Gribenko67812b22013-01-11 21:01:49 +00005938 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00005939 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005940}
5941
Argyrios Kyrtzidis9ee6a662013-04-18 22:15:49 +00005942unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
5943 if (C.kind != CXCursor_ObjCPropertyDecl)
5944 return CXObjCPropertyAttr_noattr;
5945
5946 unsigned Result = CXObjCPropertyAttr_noattr;
5947 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
5948 ObjCPropertyDecl::PropertyAttributeKind Attr =
5949 PD->getPropertyAttributesAsWritten();
5950
5951#define SET_CXOBJCPROP_ATTR(A) \
5952 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
5953 Result |= CXObjCPropertyAttr_##A
5954 SET_CXOBJCPROP_ATTR(readonly);
5955 SET_CXOBJCPROP_ATTR(getter);
5956 SET_CXOBJCPROP_ATTR(assign);
5957 SET_CXOBJCPROP_ATTR(readwrite);
5958 SET_CXOBJCPROP_ATTR(retain);
5959 SET_CXOBJCPROP_ATTR(copy);
5960 SET_CXOBJCPROP_ATTR(nonatomic);
5961 SET_CXOBJCPROP_ATTR(setter);
5962 SET_CXOBJCPROP_ATTR(atomic);
5963 SET_CXOBJCPROP_ATTR(weak);
5964 SET_CXOBJCPROP_ATTR(strong);
5965 SET_CXOBJCPROP_ATTR(unsafe_unretained);
5966#undef SET_CXOBJCPROP_ATTR
5967
5968 return Result;
5969}
5970
Argyrios Kyrtzidis38dbad22013-04-18 23:29:12 +00005971unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
5972 if (!clang_isDeclaration(C.kind))
5973 return CXObjCDeclQualifier_None;
5974
5975 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
5976 const Decl *D = getCursorDecl(C);
5977 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
5978 QT = MD->getObjCDeclQualifier();
5979 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
5980 QT = PD->getObjCDeclQualifier();
5981 if (QT == Decl::OBJC_TQ_None)
5982 return CXObjCDeclQualifier_None;
5983
5984 unsigned Result = CXObjCDeclQualifier_None;
5985 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
5986 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
5987 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
5988 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
5989 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
5990 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
5991
5992 return Result;
5993}
5994
Argyrios Kyrtzidis80e1aca2013-04-18 23:53:05 +00005995unsigned clang_Cursor_isVariadic(CXCursor C) {
5996 if (!clang_isDeclaration(C.kind))
5997 return 0;
5998
5999 const Decl *D = getCursorDecl(C);
6000 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6001 return FD->isVariadic();
6002 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6003 return MD->isVariadic();
6004
6005 return 0;
6006}
6007
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006008CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6009 if (!clang_isDeclaration(C.kind))
6010 return clang_getNullRange();
6011
6012 const Decl *D = getCursorDecl(C);
6013 ASTContext &Context = getCursorContext(C);
6014 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6015 if (!RC)
6016 return clang_getNullRange();
6017
6018 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6019}
6020
6021CXString clang_Cursor_getRawCommentText(CXCursor C) {
6022 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006023 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006024
6025 const Decl *D = getCursorDecl(C);
6026 ASTContext &Context = getCursorContext(C);
6027 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6028 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6029 StringRef();
6030
6031 // Don't duplicate the string because RawText points directly into source
6032 // code.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006033 return cxstring::createRef(RawText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006034}
6035
6036CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6037 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006038 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006039
6040 const Decl *D = getCursorDecl(C);
6041 const ASTContext &Context = getCursorContext(C);
6042 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6043
6044 if (RC) {
6045 StringRef BriefText = RC->getBriefText(Context);
6046
6047 // Don't duplicate the string because RawComment ensures that this memory
6048 // will not go away.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006049 return cxstring::createRef(BriefText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006050 }
6051
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00006052 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006053}
6054
6055CXComment clang_Cursor_getParsedComment(CXCursor C) {
6056 if (!clang_isDeclaration(C.kind))
6057 return cxcomment::createCXComment(NULL, NULL);
6058
6059 const Decl *D = getCursorDecl(C);
6060 const ASTContext &Context = getCursorContext(C);
6061 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6062
6063 return cxcomment::createCXComment(FC, getCursorTU(C));
6064}
6065
6066CXModule clang_Cursor_getModule(CXCursor C) {
6067 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006068 if (const ImportDecl *ImportD =
6069 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006070 return ImportD->getImportedModule();
6071 }
6072
6073 return 0;
6074}
6075
Argyrios Kyrtzidise858e662013-04-26 22:47:49 +00006076CXFile clang_Module_getASTFile(CXModule CXMod) {
6077 if (!CXMod)
6078 return 0;
6079 Module *Mod = static_cast<Module*>(CXMod);
6080 return const_cast<FileEntry *>(Mod->getASTFile());
6081}
6082
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006083CXModule clang_Module_getParent(CXModule CXMod) {
6084 if (!CXMod)
6085 return 0;
6086 Module *Mod = static_cast<Module*>(CXMod);
6087 return Mod->Parent;
6088}
6089
6090CXString clang_Module_getName(CXModule CXMod) {
6091 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006092 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006093 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006094 return cxstring::createDup(Mod->Name);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006095}
6096
6097CXString clang_Module_getFullName(CXModule CXMod) {
6098 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00006099 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006100 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006101 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006102}
6103
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006104unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6105 CXModule CXMod) {
6106 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006107 return 0;
6108 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006109 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6110 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6111 return TopHeaders.size();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006112}
6113
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006114CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6115 CXModule CXMod, unsigned Index) {
6116 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006117 return 0;
6118 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006119 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006120
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006121 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6122 if (Index < TopHeaders.size())
6123 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006124
6125 return 0;
6126}
6127
6128} // end: extern "C"
6129
6130//===----------------------------------------------------------------------===//
6131// C++ AST instrospection.
6132//===----------------------------------------------------------------------===//
6133
6134extern "C" {
Dmitri Gribenkoc965f762013-05-17 18:38:35 +00006135unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6136 if (!clang_isDeclaration(C.kind))
6137 return 0;
6138
6139 const CXXMethodDecl *Method = 0;
6140 const Decl *D = cxcursor::getCursorDecl(C);
6141 if (const FunctionTemplateDecl *FunTmpl =
6142 dyn_cast_or_null<FunctionTemplateDecl>(D))
6143 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6144 else
6145 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6146 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6147}
6148
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006149unsigned clang_CXXMethod_isStatic(CXCursor C) {
6150 if (!clang_isDeclaration(C.kind))
6151 return 0;
6152
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006153 const CXXMethodDecl *Method = 0;
6154 const Decl *D = cxcursor::getCursorDecl(C);
6155 if (const FunctionTemplateDecl *FunTmpl =
6156 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006157 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6158 else
6159 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6160 return (Method && Method->isStatic()) ? 1 : 0;
6161}
6162
6163unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6164 if (!clang_isDeclaration(C.kind))
6165 return 0;
6166
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006167 const CXXMethodDecl *Method = 0;
6168 const Decl *D = cxcursor::getCursorDecl(C);
6169 if (const FunctionTemplateDecl *FunTmpl =
6170 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006171 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6172 else
6173 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6174 return (Method && Method->isVirtual()) ? 1 : 0;
6175}
6176} // end: extern "C"
6177
6178//===----------------------------------------------------------------------===//
6179// Attribute introspection.
6180//===----------------------------------------------------------------------===//
6181
6182extern "C" {
6183CXType clang_getIBOutletCollectionType(CXCursor C) {
6184 if (C.kind != CXCursor_IBOutletCollectionAttr)
6185 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6186
Dmitri Gribenko7d914382013-01-26 18:08:08 +00006187 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006188 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6189
6190 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6191}
6192} // end: extern "C"
6193
6194//===----------------------------------------------------------------------===//
6195// Inspecting memory usage.
6196//===----------------------------------------------------------------------===//
6197
6198typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6199
6200static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6201 enum CXTUResourceUsageKind k,
6202 unsigned long amount) {
6203 CXTUResourceUsageEntry entry = { k, amount };
6204 entries.push_back(entry);
6205}
6206
6207extern "C" {
6208
6209const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6210 const char *str = "";
6211 switch (kind) {
6212 case CXTUResourceUsage_AST:
6213 str = "ASTContext: expressions, declarations, and types";
6214 break;
6215 case CXTUResourceUsage_Identifiers:
6216 str = "ASTContext: identifiers";
6217 break;
6218 case CXTUResourceUsage_Selectors:
6219 str = "ASTContext: selectors";
6220 break;
6221 case CXTUResourceUsage_GlobalCompletionResults:
6222 str = "Code completion: cached global results";
6223 break;
6224 case CXTUResourceUsage_SourceManagerContentCache:
6225 str = "SourceManager: content cache allocator";
6226 break;
6227 case CXTUResourceUsage_AST_SideTables:
6228 str = "ASTContext: side tables";
6229 break;
6230 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6231 str = "SourceManager: malloc'ed memory buffers";
6232 break;
6233 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6234 str = "SourceManager: mmap'ed memory buffers";
6235 break;
6236 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6237 str = "ExternalASTSource: malloc'ed memory buffers";
6238 break;
6239 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6240 str = "ExternalASTSource: mmap'ed memory buffers";
6241 break;
6242 case CXTUResourceUsage_Preprocessor:
6243 str = "Preprocessor: malloc'ed memory";
6244 break;
6245 case CXTUResourceUsage_PreprocessingRecord:
6246 str = "Preprocessor: PreprocessingRecord";
6247 break;
6248 case CXTUResourceUsage_SourceManager_DataStructures:
6249 str = "SourceManager: data structures and tables";
6250 break;
6251 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6252 str = "Preprocessor: header search tables";
6253 break;
6254 }
6255 return str;
6256}
6257
6258CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6259 if (!TU) {
6260 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6261 return usage;
6262 }
6263
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006264 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006265 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6266 ASTContext &astContext = astUnit->getASTContext();
6267
6268 // How much memory is used by AST nodes and types?
6269 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6270 (unsigned long) astContext.getASTAllocatedMemory());
6271
6272 // How much memory is used by identifiers?
6273 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6274 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6275
6276 // How much memory is used for selectors?
6277 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6278 (unsigned long) astContext.Selectors.getTotalMemory());
6279
6280 // How much memory is used by ASTContext's side tables?
6281 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6282 (unsigned long) astContext.getSideTableAllocatedMemory());
6283
6284 // How much memory is used for caching global code completion results?
6285 unsigned long completionBytes = 0;
6286 if (GlobalCodeCompletionAllocator *completionAllocator =
6287 astUnit->getCachedCompletionAllocator().getPtr()) {
6288 completionBytes = completionAllocator->getTotalMemory();
6289 }
6290 createCXTUResourceUsageEntry(*entries,
6291 CXTUResourceUsage_GlobalCompletionResults,
6292 completionBytes);
6293
6294 // How much memory is being used by SourceManager's content cache?
6295 createCXTUResourceUsageEntry(*entries,
6296 CXTUResourceUsage_SourceManagerContentCache,
6297 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6298
6299 // How much memory is being used by the MemoryBuffer's in SourceManager?
6300 const SourceManager::MemoryBufferSizes &srcBufs =
6301 astUnit->getSourceManager().getMemoryBufferSizes();
6302
6303 createCXTUResourceUsageEntry(*entries,
6304 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6305 (unsigned long) srcBufs.malloc_bytes);
6306 createCXTUResourceUsageEntry(*entries,
6307 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6308 (unsigned long) srcBufs.mmap_bytes);
6309 createCXTUResourceUsageEntry(*entries,
6310 CXTUResourceUsage_SourceManager_DataStructures,
6311 (unsigned long) astContext.getSourceManager()
6312 .getDataStructureSizes());
6313
6314 // How much memory is being used by the ExternalASTSource?
6315 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6316 const ExternalASTSource::MemoryBufferSizes &sizes =
6317 esrc->getMemoryBufferSizes();
6318
6319 createCXTUResourceUsageEntry(*entries,
6320 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6321 (unsigned long) sizes.malloc_bytes);
6322 createCXTUResourceUsageEntry(*entries,
6323 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6324 (unsigned long) sizes.mmap_bytes);
6325 }
6326
6327 // How much memory is being used by the Preprocessor?
6328 Preprocessor &pp = astUnit->getPreprocessor();
6329 createCXTUResourceUsageEntry(*entries,
6330 CXTUResourceUsage_Preprocessor,
6331 pp.getTotalMemory());
6332
6333 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6334 createCXTUResourceUsageEntry(*entries,
6335 CXTUResourceUsage_PreprocessingRecord,
6336 pRec->getTotalMemory());
6337 }
6338
6339 createCXTUResourceUsageEntry(*entries,
6340 CXTUResourceUsage_Preprocessor_HeaderSearch,
6341 pp.getHeaderSearchInfo().getTotalMemory());
6342
6343 CXTUResourceUsage usage = { (void*) entries.get(),
6344 (unsigned) entries->size(),
6345 entries->size() ? &(*entries)[0] : 0 };
6346 entries.take();
6347 return usage;
6348}
6349
6350void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6351 if (usage.data)
6352 delete (MemUsageEntries*) usage.data;
6353}
6354
6355} // end extern "C"
6356
6357void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6358 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6359 for (unsigned I = 0; I != Usage.numEntries; ++I)
6360 fprintf(stderr, " %s: %lu\n",
6361 clang_getTUResourceUsageName(Usage.entries[I].kind),
6362 Usage.entries[I].amount);
6363
6364 clang_disposeCXTUResourceUsage(Usage);
6365}
6366
6367//===----------------------------------------------------------------------===//
6368// Misc. utility functions.
6369//===----------------------------------------------------------------------===//
6370
6371/// Default to using an 8 MB stack size on "safety" threads.
6372static unsigned SafetyStackThreadSize = 8 << 20;
6373
6374namespace clang {
6375
6376bool RunSafely(llvm::CrashRecoveryContext &CRC,
6377 void (*Fn)(void*), void *UserData,
6378 unsigned Size) {
6379 if (!Size)
6380 Size = GetSafetyThreadStackSize();
6381 if (Size)
6382 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6383 return CRC.RunSafely(Fn, UserData);
6384}
6385
6386unsigned GetSafetyThreadStackSize() {
6387 return SafetyStackThreadSize;
6388}
6389
6390void SetSafetyThreadStackSize(unsigned Value) {
6391 SafetyStackThreadSize = Value;
6392}
6393
6394}
6395
6396void clang::setThreadBackgroundPriority() {
6397 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6398 return;
6399
6400 // FIXME: Move to llvm/Support and make it cross-platform.
6401#ifdef __APPLE__
6402 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6403#endif
6404}
6405
6406void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6407 if (!Unit)
6408 return;
6409
6410 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6411 DEnd = Unit->stored_diag_end();
6412 D != DEnd; ++D) {
6413 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6414 CXString Msg = clang_formatDiagnostic(&Diag,
6415 clang_defaultDiagnosticDisplayOptions());
6416 fprintf(stderr, "%s\n", clang_getCString(Msg));
6417 clang_disposeString(Msg);
6418 }
6419#ifdef LLVM_ON_WIN32
6420 // On Windows, force a flush, since there may be multiple copies of
6421 // stderr and stdout in the file system, all with different buffers
6422 // but writing to the same device.
6423 fflush(stderr);
6424#endif
6425}
6426
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006427MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6428 SourceLocation MacroDefLoc,
6429 CXTranslationUnit TU){
6430 if (MacroDefLoc.isInvalid() || !TU)
6431 return 0;
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006432 if (!II.hadMacroDefinition())
6433 return 0;
6434
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006435 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00006436 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006437 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006438 if (MD) {
6439 for (MacroDirective::DefInfo
6440 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6441 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6442 return Def.getMacroInfo();
6443 }
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006444 }
6445
6446 return 0;
6447}
6448
Dmitri Gribenko67812b22013-01-11 21:01:49 +00006449const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6450 CXTranslationUnit TU) {
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006451 if (!MacroDef || !TU)
6452 return 0;
6453 const IdentifierInfo *II = MacroDef->getName();
6454 if (!II)
6455 return 0;
6456
6457 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6458}
6459
6460MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6461 const Token &Tok,
6462 CXTranslationUnit TU) {
6463 if (!MI || !TU)
6464 return 0;
6465 if (Tok.isNot(tok::raw_identifier))
6466 return 0;
6467
6468 if (MI->getNumTokens() == 0)
6469 return 0;
6470 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6471 MI->getDefinitionEndLoc());
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006472 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006473
6474 // Check that the token is inside the definition and not its argument list.
6475 SourceManager &SM = Unit->getSourceManager();
6476 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6477 return 0;
6478 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6479 return 0;
6480
6481 Preprocessor &PP = Unit->getPreprocessor();
6482 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6483 if (!PPRec)
6484 return 0;
6485
6486 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6487 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6488 if (!II.hadMacroDefinition())
6489 return 0;
6490
6491 // Check that the identifier is not one of the macro arguments.
6492 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6493 return 0;
6494
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006495 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6496 if (!InnerMD)
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006497 return 0;
6498
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006499 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006500}
6501
6502MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6503 SourceLocation Loc,
6504 CXTranslationUnit TU) {
6505 if (Loc.isInvalid() || !MI || !TU)
6506 return 0;
6507
6508 if (MI->getNumTokens() == 0)
6509 return 0;
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006510 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006511 Preprocessor &PP = Unit->getPreprocessor();
6512 if (!PP.getPreprocessingRecord())
6513 return 0;
6514 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6515 Token Tok;
6516 if (PP.getRawToken(Loc, Tok))
6517 return 0;
6518
6519 return checkForMacroInMacroDefinition(MI, Tok, TU);
6520}
6521
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006522extern "C" {
6523
6524CXString clang_getClangVersion() {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006525 return cxstring::createDup(getClangFullVersion());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006526}
6527
6528} // end: extern "C"
6529
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006530Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6531 if (TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006532 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006533 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis44f65a52013-03-05 20:21:14 +00006534 if (Unit->isMainFileAST())
6535 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006536 return *this;
6537 }
6538 }
6539
6540 LogOS << "<NULL TU>";
6541 return *this;
6542}
6543
Argyrios Kyrtzidisb70e7a82013-03-08 02:32:26 +00006544Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6545 *this << FE->getName();
6546 return *this;
6547}
6548
6549Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6550 CXString cursorName = clang_getCursorDisplayName(cursor);
6551 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6552 clang_disposeString(cursorName);
6553 return *this;
6554}
6555
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006556Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6557 CXFile File;
6558 unsigned Line, Column;
6559 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6560 CXString FileName = clang_getFileName(File);
6561 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6562 clang_disposeString(FileName);
6563 return *this;
6564}
6565
6566Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6567 CXSourceLocation BLoc = clang_getRangeStart(range);
6568 CXSourceLocation ELoc = clang_getRangeEnd(range);
6569
6570 CXFile BFile;
6571 unsigned BLine, BColumn;
6572 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6573
6574 CXFile EFile;
6575 unsigned ELine, EColumn;
6576 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6577
6578 CXString BFileName = clang_getFileName(BFile);
6579 if (BFile == EFile) {
6580 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6581 BLine, BColumn, ELine, EColumn);
6582 } else {
6583 CXString EFileName = clang_getFileName(EFile);
6584 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6585 BLine, BColumn)
6586 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6587 ELine, EColumn);
6588 clang_disposeString(EFileName);
6589 }
6590 clang_disposeString(BFileName);
6591 return *this;
6592}
6593
6594Logger &cxindex::Logger::operator<<(CXString Str) {
6595 *this << clang_getCString(Str);
6596 return *this;
6597}
6598
6599Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6600 LogOS << Fmt;
6601 return *this;
6602}
6603
6604cxindex::Logger::~Logger() {
6605 LogOS.flush();
6606
6607 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6608
6609 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6610
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00006611 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006612 OS << "[libclang:" << Name << ':';
6613
6614 // FIXME: Portability.
6615#if HAVE_PTHREAD_H && __APPLE__
6616 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6617 OS << tid << ':';
6618#endif
6619
6620 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6621 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6622 OS << Msg.str() << '\n';
6623
6624 if (Trace) {
6625 llvm::sys::PrintStackTrace(stderr);
6626 OS << "--------------------------------------------------\n";
6627 }
6628}