blob: a81f1e437d283ac5afb2578da12449ce89ef1dc1 [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;
429 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
430 if (Visit(MakeMacroExpansionCursor(ME, TU)))
431 return true;
432
433 continue;
434 }
435
436 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
437 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
438 return true;
439
440 continue;
441 }
442
443 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
444 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
445 return true;
446
447 continue;
448 }
449 }
450
451 return false;
452}
453
454/// \brief Visit the children of the given cursor.
455///
456/// \returns true if the visitation should be aborted, false if it
457/// should continue.
458bool CursorVisitor::VisitChildren(CXCursor Cursor) {
459 if (clang_isReference(Cursor.kind) &&
460 Cursor.kind != CXCursor_CXXBaseSpecifier) {
461 // By definition, references have no children.
462 return false;
463 }
464
465 // Set the Parent field to Cursor, then back to its old value once we're
466 // done.
467 SetParentRAII SetParent(Parent, StmtParent, Cursor);
468
469 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +0000470 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000471 if (!D)
472 return false;
473
474 return VisitAttributes(D) || Visit(D);
475 }
476
477 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +0000478 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000479 return Visit(S);
480
481 return false;
482 }
483
484 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +0000485 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000486 return Visit(E);
487
488 return false;
489 }
490
491 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000492 CXTranslationUnit TU = getCursorTU(Cursor);
493 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000494
495 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
496 for (unsigned I = 0; I != 2; ++I) {
497 if (VisitOrder[I]) {
498 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
499 RegionOfInterest.isInvalid()) {
500 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
501 TLEnd = CXXUnit->top_level_end();
502 TL != TLEnd; ++TL) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +0000503 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000504 return true;
505 }
506 } else if (VisitDeclContext(
507 CXXUnit->getASTContext().getTranslationUnitDecl()))
508 return true;
509 continue;
510 }
511
512 // Walk the preprocessing record.
513 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
514 visitPreprocessedEntitiesInRegion();
515 }
516
517 return false;
518 }
519
520 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +0000521 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000522 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
523 return Visit(BaseTSInfo->getTypeLoc());
524 }
525 }
526 }
527
528 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +0000529 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000530 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
531 if (const ObjCInterfaceType *InterT = A->getInterface()->getAs<ObjCInterfaceType>())
532 return Visit(cxcursor::MakeCursorObjCClassRef(InterT->getInterface(),
533 A->getInterfaceLoc(), TU));
534 }
535
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +0000536 // If pointing inside a macro definition, check if the token is an identifier
537 // that was ever defined as a macro. In such a case, create a "pseudo" macro
538 // expansion cursor for that token.
539 SourceLocation BeginLoc = RegionOfInterest.getBegin();
540 if (Cursor.kind == CXCursor_MacroDefinition &&
541 BeginLoc == RegionOfInterest.getEnd()) {
542 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenko67812b22013-01-11 21:01:49 +0000543 const MacroInfo *MI =
544 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +0000545 if (MacroDefinition *MacroDef =
546 checkForMacroInMacroDefinition(MI, Loc, TU))
547 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
548 }
549
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000550 // Nothing to visit at the moment.
551 return false;
552}
553
554bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
555 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
556 if (Visit(TSInfo->getTypeLoc()))
557 return true;
558
559 if (Stmt *Body = B->getBody())
560 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
561
562 return false;
563}
564
Ted Kremenek943f9092013-02-21 01:29:01 +0000565Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000566 if (RegionOfInterest.isValid()) {
567 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
568 if (Range.isInvalid())
David Blaikie66874fb2013-02-21 01:47:18 +0000569 return None;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000570
571 switch (CompareRegionOfInterest(Range)) {
572 case RangeBefore:
573 // This declaration comes before the region of interest; skip it.
David Blaikie66874fb2013-02-21 01:47:18 +0000574 return None;
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000575
576 case RangeAfter:
577 // This declaration comes after the region of interest; we're done.
578 return false;
579
580 case RangeOverlap:
581 // This declaration overlaps the region of interest; visit it.
582 break;
583 }
584 }
585 return true;
586}
587
588bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
589 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
590
591 // FIXME: Eventually remove. This part of a hack to support proper
592 // iteration over all Decls contained lexically within an ObjC container.
593 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
594 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
595
596 for ( ; I != E; ++I) {
597 Decl *D = *I;
598 if (D->getLexicalDeclContext() != DC)
599 continue;
600 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
601
602 // Ignore synthesized ivars here, otherwise if we have something like:
603 // @synthesize prop = _prop;
604 // and '_prop' is not declared, we will encounter a '_prop' ivar before
605 // encountering the 'prop' synthesize declaration and we will think that
606 // we passed the region-of-interest.
607 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
608 if (ivarD->getSynthesize())
609 continue;
610 }
611
612 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
613 // declarations is a mismatch with the compiler semantics.
614 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
615 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
616 if (!ID->isThisDeclarationADefinition())
617 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
618
619 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
620 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
621 if (!PD->isThisDeclarationADefinition())
622 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
623 }
624
Ted Kremenek943f9092013-02-21 01:29:01 +0000625 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000626 if (!V.hasValue())
627 continue;
628 if (!V.getValue())
629 return false;
630 if (Visit(Cursor, true))
631 return true;
632 }
633 return false;
634}
635
636bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
637 llvm_unreachable("Translation units are visited directly by Visit()");
638}
639
640bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
641 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
642 return Visit(TSInfo->getTypeLoc());
643
644 return false;
645}
646
647bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
648 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
649 return Visit(TSInfo->getTypeLoc());
650
651 return false;
652}
653
654bool CursorVisitor::VisitTagDecl(TagDecl *D) {
655 return VisitDeclContext(D);
656}
657
658bool CursorVisitor::VisitClassTemplateSpecializationDecl(
659 ClassTemplateSpecializationDecl *D) {
660 bool ShouldVisitBody = false;
661 switch (D->getSpecializationKind()) {
662 case TSK_Undeclared:
663 case TSK_ImplicitInstantiation:
664 // Nothing to visit
665 return false;
666
667 case TSK_ExplicitInstantiationDeclaration:
668 case TSK_ExplicitInstantiationDefinition:
669 break;
670
671 case TSK_ExplicitSpecialization:
672 ShouldVisitBody = true;
673 break;
674 }
675
676 // Visit the template arguments used in the specialization.
677 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
678 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie39e6ab42013-02-18 22:06:02 +0000679 if (TemplateSpecializationTypeLoc TSTLoc =
680 TL.getAs<TemplateSpecializationTypeLoc>()) {
681 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
682 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000683 return true;
684 }
685 }
686
687 if (ShouldVisitBody && VisitCXXRecordDecl(D))
688 return true;
689
690 return false;
691}
692
693bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
694 ClassTemplatePartialSpecializationDecl *D) {
695 // FIXME: Visit the "outer" template parameter lists on the TagDecl
696 // before visiting these template parameters.
697 if (VisitTemplateParameters(D->getTemplateParameters()))
698 return true;
699
700 // Visit the partial specialization arguments.
701 const TemplateArgumentLoc *TemplateArgs = D->getTemplateArgsAsWritten();
702 for (unsigned I = 0, N = D->getNumTemplateArgsAsWritten(); I != N; ++I)
703 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
704 return true;
705
706 return VisitCXXRecordDecl(D);
707}
708
709bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
710 // Visit the default argument.
711 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
712 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
713 if (Visit(DefArg->getTypeLoc()))
714 return true;
715
716 return false;
717}
718
719bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
720 if (Expr *Init = D->getInitExpr())
721 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
722 return false;
723}
724
725bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
726 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
727 if (Visit(TSInfo->getTypeLoc()))
728 return true;
729
730 // Visit the nested-name-specifier, if present.
731 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
732 if (VisitNestedNameSpecifierLoc(QualifierLoc))
733 return true;
734
735 return false;
736}
737
738/// \brief Compare two base or member initializers based on their source order.
739static int CompareCXXCtorInitializers(const void* Xp, const void *Yp) {
740 CXXCtorInitializer const * const *X
741 = static_cast<CXXCtorInitializer const * const *>(Xp);
742 CXXCtorInitializer const * const *Y
743 = static_cast<CXXCtorInitializer const * const *>(Yp);
744
745 if ((*X)->getSourceOrder() < (*Y)->getSourceOrder())
746 return -1;
747 else if ((*X)->getSourceOrder() > (*Y)->getSourceOrder())
748 return 1;
749 else
750 return 0;
751}
752
753bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
754 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
755 // Visit the function declaration's syntactic components in the order
756 // written. This requires a bit of work.
757 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie39e6ab42013-02-18 22:06:02 +0000758 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000759
760 // If we have a function declared directly (without the use of a typedef),
761 // visit just the return type. Otherwise, just visit the function's type
762 // now.
David Blaikie39e6ab42013-02-18 22:06:02 +0000763 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getResultLoc())) ||
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000764 (!FTL && Visit(TL)))
765 return true;
766
767 // Visit the nested-name-specifier, if present.
768 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
769 if (VisitNestedNameSpecifierLoc(QualifierLoc))
770 return true;
771
772 // Visit the declaration name.
773 if (VisitDeclarationNameInfo(ND->getNameInfo()))
774 return true;
775
776 // FIXME: Visit explicitly-specified template arguments!
777
778 // Visit the function parameters, if we have a function type.
David Blaikie39e6ab42013-02-18 22:06:02 +0000779 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000780 return true;
781
Bill Wendlingad017fa2012-12-20 19:22:21 +0000782 // FIXME: Attributes?
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000783 }
784
785 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
786 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
787 // Find the initializers that were written in the source.
788 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
789 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
790 IEnd = Constructor->init_end();
791 I != IEnd; ++I) {
792 if (!(*I)->isWritten())
793 continue;
794
795 WrittenInits.push_back(*I);
796 }
797
798 // Sort the initializers in source order
799 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
800 &CompareCXXCtorInitializers);
801
802 // Visit the initializers in source order
803 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
804 CXXCtorInitializer *Init = WrittenInits[I];
805 if (Init->isAnyMemberInitializer()) {
806 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
807 Init->getMemberLocation(), TU)))
808 return true;
809 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
810 if (Visit(TInfo->getTypeLoc()))
811 return true;
812 }
813
814 // Visit the initializer value.
815 if (Expr *Initializer = Init->getInit())
816 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
817 return true;
818 }
819 }
820
821 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
822 return true;
823 }
824
825 return false;
826}
827
828bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
829 if (VisitDeclaratorDecl(D))
830 return true;
831
832 if (Expr *BitWidth = D->getBitWidth())
833 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
834
835 return false;
836}
837
838bool CursorVisitor::VisitVarDecl(VarDecl *D) {
839 if (VisitDeclaratorDecl(D))
840 return true;
841
842 if (Expr *Init = D->getInit())
843 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
844
845 return false;
846}
847
848bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
849 if (VisitDeclaratorDecl(D))
850 return true;
851
852 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
853 if (Expr *DefArg = D->getDefaultArgument())
854 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
855
856 return false;
857}
858
859bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
860 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
861 // before visiting these template parameters.
862 if (VisitTemplateParameters(D->getTemplateParameters()))
863 return true;
864
865 return VisitFunctionDecl(D->getTemplatedDecl());
866}
867
868bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
869 // FIXME: Visit the "outer" template parameter lists on the TagDecl
870 // before visiting these template parameters.
871 if (VisitTemplateParameters(D->getTemplateParameters()))
872 return true;
873
874 return VisitCXXRecordDecl(D->getTemplatedDecl());
875}
876
877bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
878 if (VisitTemplateParameters(D->getTemplateParameters()))
879 return true;
880
881 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
882 VisitTemplateArgumentLoc(D->getDefaultArgument()))
883 return true;
884
885 return false;
886}
887
888bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
889 if (TypeSourceInfo *TSInfo = ND->getResultTypeSourceInfo())
890 if (Visit(TSInfo->getTypeLoc()))
891 return true;
892
893 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
894 PEnd = ND->param_end();
895 P != PEnd; ++P) {
896 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
897 return true;
898 }
899
900 if (ND->isThisDeclarationADefinition() &&
901 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
902 return true;
903
904 return false;
905}
906
907template <typename DeclIt>
908static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
909 SourceManager &SM, SourceLocation EndLoc,
910 SmallVectorImpl<Decl *> &Decls) {
911 DeclIt next = *DI_current;
912 while (++next != DE_current) {
913 Decl *D_next = *next;
914 if (!D_next)
915 break;
916 SourceLocation L = D_next->getLocStart();
917 if (!L.isValid())
918 break;
919 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
920 *DI_current = next;
921 Decls.push_back(D_next);
922 continue;
923 }
924 break;
925 }
926}
927
928namespace {
929 struct ContainerDeclsSort {
930 SourceManager &SM;
931 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
932 bool operator()(Decl *A, Decl *B) {
933 SourceLocation L_A = A->getLocStart();
934 SourceLocation L_B = B->getLocStart();
935 assert(L_A.isValid() && L_B.isValid());
936 return SM.isBeforeInTranslationUnit(L_A, L_B);
937 }
938 };
939}
940
941bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
942 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
943 // an @implementation can lexically contain Decls that are not properly
944 // nested in the AST. When we identify such cases, we need to retrofit
945 // this nesting here.
946 if (!DI_current && !FileDI_current)
947 return VisitDeclContext(D);
948
949 // Scan the Decls that immediately come after the container
950 // in the current DeclContext. If any fall within the
951 // container's lexical region, stash them into a vector
952 // for later processing.
953 SmallVector<Decl *, 24> DeclsInContainer;
954 SourceLocation EndLoc = D->getSourceRange().getEnd();
955 SourceManager &SM = AU->getSourceManager();
956 if (EndLoc.isValid()) {
957 if (DI_current) {
958 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
959 DeclsInContainer);
960 } else {
961 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
962 DeclsInContainer);
963 }
964 }
965
966 // The common case.
967 if (DeclsInContainer.empty())
968 return VisitDeclContext(D);
969
970 // Get all the Decls in the DeclContext, and sort them with the
971 // additional ones we've collected. Then visit them.
972 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
973 I!=E; ++I) {
974 Decl *subDecl = *I;
975 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
976 subDecl->getLocStart().isInvalid())
977 continue;
978 DeclsInContainer.push_back(subDecl);
979 }
980
981 // Now sort the Decls so that they appear in lexical order.
982 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
983 ContainerDeclsSort(SM));
984
985 // Now visit the decls.
986 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
987 E = DeclsInContainer.end(); I != E; ++I) {
988 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek943f9092013-02-21 01:29:01 +0000989 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +0000990 if (!V.hasValue())
991 continue;
992 if (!V.getValue())
993 return false;
994 if (Visit(Cursor, true))
995 return true;
996 }
997 return false;
998}
999
1000bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1001 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1002 TU)))
1003 return true;
1004
1005 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1006 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1007 E = ND->protocol_end(); I != E; ++I, ++PL)
1008 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1009 return true;
1010
1011 return VisitObjCContainerDecl(ND);
1012}
1013
1014bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1015 if (!PID->isThisDeclarationADefinition())
1016 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1017
1018 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1019 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1020 E = PID->protocol_end(); I != E; ++I, ++PL)
1021 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1022 return true;
1023
1024 return VisitObjCContainerDecl(PID);
1025}
1026
1027bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1028 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1029 return true;
1030
1031 // FIXME: This implements a workaround with @property declarations also being
1032 // installed in the DeclContext for the @interface. Eventually this code
1033 // should be removed.
1034 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1035 if (!CDecl || !CDecl->IsClassExtension())
1036 return false;
1037
1038 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1039 if (!ID)
1040 return false;
1041
1042 IdentifierInfo *PropertyId = PD->getIdentifier();
1043 ObjCPropertyDecl *prevDecl =
1044 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1045
1046 if (!prevDecl)
1047 return false;
1048
1049 // Visit synthesized methods since they will be skipped when visiting
1050 // the @interface.
1051 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1052 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1053 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1054 return true;
1055
1056 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1057 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1058 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1059 return true;
1060
1061 return false;
1062}
1063
1064bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1065 if (!D->isThisDeclarationADefinition()) {
1066 // Forward declaration is treated like a reference.
1067 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1068 }
1069
1070 // Issue callbacks for super class.
1071 if (D->getSuperClass() &&
1072 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1073 D->getSuperClassLoc(),
1074 TU)))
1075 return true;
1076
1077 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1078 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1079 E = D->protocol_end(); I != E; ++I, ++PL)
1080 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1081 return true;
1082
1083 return VisitObjCContainerDecl(D);
1084}
1085
1086bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1087 return VisitObjCContainerDecl(D);
1088}
1089
1090bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1091 // 'ID' could be null when dealing with invalid code.
1092 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1093 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1094 return true;
1095
1096 return VisitObjCImplDecl(D);
1097}
1098
1099bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1100#if 0
1101 // Issue callbacks for super class.
1102 // FIXME: No source location information!
1103 if (D->getSuperClass() &&
1104 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1105 D->getSuperClassLoc(),
1106 TU)))
1107 return true;
1108#endif
1109
1110 return VisitObjCImplDecl(D);
1111}
1112
1113bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1114 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1115 if (PD->isIvarNameSpecified())
1116 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1117
1118 return false;
1119}
1120
1121bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1122 return VisitDeclContext(D);
1123}
1124
1125bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1126 // Visit nested-name-specifier.
1127 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1128 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1129 return true;
1130
1131 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1132 D->getTargetNameLoc(), TU));
1133}
1134
1135bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1136 // Visit nested-name-specifier.
1137 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1138 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1139 return true;
1140 }
1141
1142 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1143 return true;
1144
1145 return VisitDeclarationNameInfo(D->getNameInfo());
1146}
1147
1148bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1149 // Visit nested-name-specifier.
1150 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1151 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1152 return true;
1153
1154 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1155 D->getIdentLocation(), TU));
1156}
1157
1158bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1159 // Visit nested-name-specifier.
1160 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1161 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1162 return true;
1163 }
1164
1165 return VisitDeclarationNameInfo(D->getNameInfo());
1166}
1167
1168bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1169 UnresolvedUsingTypenameDecl *D) {
1170 // Visit nested-name-specifier.
1171 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1172 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1173 return true;
1174
1175 return false;
1176}
1177
1178bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1179 switch (Name.getName().getNameKind()) {
1180 case clang::DeclarationName::Identifier:
1181 case clang::DeclarationName::CXXLiteralOperatorName:
1182 case clang::DeclarationName::CXXOperatorName:
1183 case clang::DeclarationName::CXXUsingDirective:
1184 return false;
1185
1186 case clang::DeclarationName::CXXConstructorName:
1187 case clang::DeclarationName::CXXDestructorName:
1188 case clang::DeclarationName::CXXConversionFunctionName:
1189 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1190 return Visit(TSInfo->getTypeLoc());
1191 return false;
1192
1193 case clang::DeclarationName::ObjCZeroArgSelector:
1194 case clang::DeclarationName::ObjCOneArgSelector:
1195 case clang::DeclarationName::ObjCMultiArgSelector:
1196 // FIXME: Per-identifier location info?
1197 return false;
1198 }
1199
1200 llvm_unreachable("Invalid DeclarationName::Kind!");
1201}
1202
1203bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1204 SourceRange Range) {
1205 // FIXME: This whole routine is a hack to work around the lack of proper
1206 // source information in nested-name-specifiers (PR5791). Since we do have
1207 // a beginning source location, we can visit the first component of the
1208 // nested-name-specifier, if it's a single-token component.
1209 if (!NNS)
1210 return false;
1211
1212 // Get the first component in the nested-name-specifier.
1213 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1214 NNS = Prefix;
1215
1216 switch (NNS->getKind()) {
1217 case NestedNameSpecifier::Namespace:
1218 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1219 TU));
1220
1221 case NestedNameSpecifier::NamespaceAlias:
1222 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1223 Range.getBegin(), TU));
1224
1225 case NestedNameSpecifier::TypeSpec: {
1226 // If the type has a form where we know that the beginning of the source
1227 // range matches up with a reference cursor. Visit the appropriate reference
1228 // cursor.
1229 const Type *T = NNS->getAsType();
1230 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1231 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1232 if (const TagType *Tag = dyn_cast<TagType>(T))
1233 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1234 if (const TemplateSpecializationType *TST
1235 = dyn_cast<TemplateSpecializationType>(T))
1236 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1237 break;
1238 }
1239
1240 case NestedNameSpecifier::TypeSpecWithTemplate:
1241 case NestedNameSpecifier::Global:
1242 case NestedNameSpecifier::Identifier:
1243 break;
1244 }
1245
1246 return false;
1247}
1248
1249bool
1250CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1251 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1252 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1253 Qualifiers.push_back(Qualifier);
1254
1255 while (!Qualifiers.empty()) {
1256 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1257 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1258 switch (NNS->getKind()) {
1259 case NestedNameSpecifier::Namespace:
1260 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1261 Q.getLocalBeginLoc(),
1262 TU)))
1263 return true;
1264
1265 break;
1266
1267 case NestedNameSpecifier::NamespaceAlias:
1268 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1269 Q.getLocalBeginLoc(),
1270 TU)))
1271 return true;
1272
1273 break;
1274
1275 case NestedNameSpecifier::TypeSpec:
1276 case NestedNameSpecifier::TypeSpecWithTemplate:
1277 if (Visit(Q.getTypeLoc()))
1278 return true;
1279
1280 break;
1281
1282 case NestedNameSpecifier::Global:
1283 case NestedNameSpecifier::Identifier:
1284 break;
1285 }
1286 }
1287
1288 return false;
1289}
1290
1291bool CursorVisitor::VisitTemplateParameters(
1292 const TemplateParameterList *Params) {
1293 if (!Params)
1294 return false;
1295
1296 for (TemplateParameterList::const_iterator P = Params->begin(),
1297 PEnd = Params->end();
1298 P != PEnd; ++P) {
1299 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1300 return true;
1301 }
1302
1303 return false;
1304}
1305
1306bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1307 switch (Name.getKind()) {
1308 case TemplateName::Template:
1309 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1310
1311 case TemplateName::OverloadedTemplate:
1312 // Visit the overloaded template set.
1313 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1314 return true;
1315
1316 return false;
1317
1318 case TemplateName::DependentTemplate:
1319 // FIXME: Visit nested-name-specifier.
1320 return false;
1321
1322 case TemplateName::QualifiedTemplate:
1323 // FIXME: Visit nested-name-specifier.
1324 return Visit(MakeCursorTemplateRef(
1325 Name.getAsQualifiedTemplateName()->getDecl(),
1326 Loc, TU));
1327
1328 case TemplateName::SubstTemplateTemplateParm:
1329 return Visit(MakeCursorTemplateRef(
1330 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1331 Loc, TU));
1332
1333 case TemplateName::SubstTemplateTemplateParmPack:
1334 return Visit(MakeCursorTemplateRef(
1335 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1336 Loc, TU));
1337 }
1338
1339 llvm_unreachable("Invalid TemplateName::Kind!");
1340}
1341
1342bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1343 switch (TAL.getArgument().getKind()) {
1344 case TemplateArgument::Null:
1345 case TemplateArgument::Integral:
1346 case TemplateArgument::Pack:
1347 return false;
1348
1349 case TemplateArgument::Type:
1350 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1351 return Visit(TSInfo->getTypeLoc());
1352 return false;
1353
1354 case TemplateArgument::Declaration:
1355 if (Expr *E = TAL.getSourceDeclExpression())
1356 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1357 return false;
1358
1359 case TemplateArgument::NullPtr:
1360 if (Expr *E = TAL.getSourceNullPtrExpression())
1361 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1362 return false;
1363
1364 case TemplateArgument::Expression:
1365 if (Expr *E = TAL.getSourceExpression())
1366 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1367 return false;
1368
1369 case TemplateArgument::Template:
1370 case TemplateArgument::TemplateExpansion:
1371 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1372 return true;
1373
1374 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1375 TAL.getTemplateNameLoc());
1376 }
1377
1378 llvm_unreachable("Invalid TemplateArgument::Kind!");
1379}
1380
1381bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1382 return VisitDeclContext(D);
1383}
1384
1385bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1386 return Visit(TL.getUnqualifiedLoc());
1387}
1388
1389bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1390 ASTContext &Context = AU->getASTContext();
1391
1392 // Some builtin types (such as Objective-C's "id", "sel", and
1393 // "Class") have associated declarations. Create cursors for those.
1394 QualType VisitType;
1395 switch (TL.getTypePtr()->getKind()) {
1396
1397 case BuiltinType::Void:
1398 case BuiltinType::NullPtr:
1399 case BuiltinType::Dependent:
Guy Benyeib13621d2012-12-18 14:38:23 +00001400 case BuiltinType::OCLImage1d:
1401 case BuiltinType::OCLImage1dArray:
1402 case BuiltinType::OCLImage1dBuffer:
1403 case BuiltinType::OCLImage2d:
1404 case BuiltinType::OCLImage2dArray:
1405 case BuiltinType::OCLImage3d:
NAKAMURA Takumi775bb8a2013-02-07 12:47:42 +00001406 case BuiltinType::OCLSampler:
Guy Benyeie6b9d802013-01-20 12:31:11 +00001407 case BuiltinType::OCLEvent:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001408#define BUILTIN_TYPE(Id, SingletonId)
1409#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1410#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1411#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1412#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1413#include "clang/AST/BuiltinTypes.def"
1414 break;
1415
1416 case BuiltinType::ObjCId:
1417 VisitType = Context.getObjCIdType();
1418 break;
1419
1420 case BuiltinType::ObjCClass:
1421 VisitType = Context.getObjCClassType();
1422 break;
1423
1424 case BuiltinType::ObjCSel:
1425 VisitType = Context.getObjCSelType();
1426 break;
1427 }
1428
1429 if (!VisitType.isNull()) {
1430 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1431 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1432 TU));
1433 }
1434
1435 return false;
1436}
1437
1438bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1439 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1440}
1441
1442bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1443 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1444}
1445
1446bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1447 if (TL.isDefinition())
1448 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1449
1450 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1451}
1452
1453bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1454 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1455}
1456
1457bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1458 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1459 return true;
1460
1461 return false;
1462}
1463
1464bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1465 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1466 return true;
1467
1468 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1469 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1470 TU)))
1471 return true;
1472 }
1473
1474 return false;
1475}
1476
1477bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1478 return Visit(TL.getPointeeLoc());
1479}
1480
1481bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1482 return Visit(TL.getInnerLoc());
1483}
1484
1485bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1486 return Visit(TL.getPointeeLoc());
1487}
1488
1489bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1490 return Visit(TL.getPointeeLoc());
1491}
1492
1493bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1494 return Visit(TL.getPointeeLoc());
1495}
1496
1497bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1498 return Visit(TL.getPointeeLoc());
1499}
1500
1501bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1502 return Visit(TL.getPointeeLoc());
1503}
1504
1505bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1506 return Visit(TL.getModifiedLoc());
1507}
1508
1509bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1510 bool SkipResultType) {
1511 if (!SkipResultType && Visit(TL.getResultLoc()))
1512 return true;
1513
1514 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1515 if (Decl *D = TL.getArg(I))
1516 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1517 return true;
1518
1519 return false;
1520}
1521
1522bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1523 if (Visit(TL.getElementLoc()))
1524 return true;
1525
1526 if (Expr *Size = TL.getSizeExpr())
1527 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1528
1529 return false;
1530}
1531
1532bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1533 TemplateSpecializationTypeLoc TL) {
1534 // Visit the template name.
1535 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1536 TL.getTemplateNameLoc()))
1537 return true;
1538
1539 // Visit the template arguments.
1540 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1541 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1542 return true;
1543
1544 return false;
1545}
1546
1547bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1548 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1549}
1550
1551bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1552 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1553 return Visit(TSInfo->getTypeLoc());
1554
1555 return false;
1556}
1557
1558bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1559 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1560 return Visit(TSInfo->getTypeLoc());
1561
1562 return false;
1563}
1564
1565bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1566 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1567 return true;
1568
1569 return false;
1570}
1571
1572bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1573 DependentTemplateSpecializationTypeLoc TL) {
1574 // Visit the nested-name-specifier, if there is one.
1575 if (TL.getQualifierLoc() &&
1576 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1577 return true;
1578
1579 // Visit the template arguments.
1580 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1581 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1582 return true;
1583
1584 return false;
1585}
1586
1587bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1588 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1589 return true;
1590
1591 return Visit(TL.getNamedTypeLoc());
1592}
1593
1594bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1595 return Visit(TL.getPatternLoc());
1596}
1597
1598bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1599 if (Expr *E = TL.getUnderlyingExpr())
1600 return Visit(MakeCXCursor(E, StmtParent, TU));
1601
1602 return false;
1603}
1604
1605bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1606 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1607}
1608
1609bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1610 return Visit(TL.getValueLoc());
1611}
1612
1613#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1614bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1615 return Visit##PARENT##Loc(TL); \
1616}
1617
1618DEFAULT_TYPELOC_IMPL(Complex, Type)
1619DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1620DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1621DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1622DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1623DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1624DEFAULT_TYPELOC_IMPL(Vector, Type)
1625DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1626DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1627DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1628DEFAULT_TYPELOC_IMPL(Record, TagType)
1629DEFAULT_TYPELOC_IMPL(Enum, TagType)
1630DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1631DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1632DEFAULT_TYPELOC_IMPL(Auto, Type)
1633
1634bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1635 // Visit the nested-name-specifier, if present.
1636 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1637 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1638 return true;
1639
1640 if (D->isCompleteDefinition()) {
1641 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1642 E = D->bases_end(); I != E; ++I) {
1643 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1644 return true;
1645 }
1646 }
1647
1648 return VisitTagDecl(D);
1649}
1650
1651bool CursorVisitor::VisitAttributes(Decl *D) {
1652 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1653 i != e; ++i)
1654 if (Visit(MakeCXCursor(*i, D, TU)))
1655 return true;
1656
1657 return false;
1658}
1659
1660//===----------------------------------------------------------------------===//
1661// Data-recursive visitor methods.
1662//===----------------------------------------------------------------------===//
1663
1664namespace {
1665#define DEF_JOB(NAME, DATA, KIND)\
1666class NAME : public VisitorJob {\
1667public:\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001668 NAME(const DATA *d, CXCursor parent) : \
1669 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001670 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001671 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001672};
1673
1674DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1675DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1676DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1677DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1678DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1679 ExplicitTemplateArgsVisitKind)
1680DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1681DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1682DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1683#undef DEF_JOB
1684
1685class DeclVisit : public VisitorJob {
1686public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001687 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001688 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001689 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001690 static bool classof(const VisitorJob *VJ) {
1691 return VJ->getKind() == DeclVisitKind;
1692 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001693 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001694 bool isFirst() const { return data[1] ? true : false; }
1695};
1696class TypeLocVisit : public VisitorJob {
1697public:
1698 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1699 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1700 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1701
1702 static bool classof(const VisitorJob *VJ) {
1703 return VJ->getKind() == TypeLocVisitKind;
1704 }
1705
1706 TypeLoc get() const {
1707 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001708 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001709 }
1710};
1711
1712class LabelRefVisit : public VisitorJob {
1713public:
1714 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1715 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1716 labelLoc.getPtrEncoding()) {}
1717
1718 static bool classof(const VisitorJob *VJ) {
1719 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1720 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001721 const LabelDecl *get() const {
1722 return static_cast<const LabelDecl *>(data[0]);
1723 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001724 SourceLocation getLoc() const {
1725 return SourceLocation::getFromPtrEncoding(data[1]); }
1726};
1727
1728class NestedNameSpecifierLocVisit : public VisitorJob {
1729public:
1730 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1731 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1732 Qualifier.getNestedNameSpecifier(),
1733 Qualifier.getOpaqueData()) { }
1734
1735 static bool classof(const VisitorJob *VJ) {
1736 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1737 }
1738
1739 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001740 return NestedNameSpecifierLoc(
1741 const_cast<NestedNameSpecifier *>(
1742 static_cast<const NestedNameSpecifier *>(data[0])),
1743 const_cast<void *>(data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001744 }
1745};
1746
1747class DeclarationNameInfoVisit : public VisitorJob {
1748public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001749 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkoa376f872013-02-03 13:19:54 +00001750 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001751 static bool classof(const VisitorJob *VJ) {
1752 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1753 }
1754 DeclarationNameInfo get() const {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001755 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001756 switch (S->getStmtClass()) {
1757 default:
1758 llvm_unreachable("Unhandled Stmt");
1759 case clang::Stmt::MSDependentExistsStmtClass:
1760 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1761 case Stmt::CXXDependentScopeMemberExprClass:
1762 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1763 case Stmt::DependentScopeDeclRefExprClass:
1764 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1765 }
1766 }
1767};
1768class MemberRefVisit : public VisitorJob {
1769public:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001770 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001771 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1772 L.getPtrEncoding()) {}
1773 static bool classof(const VisitorJob *VJ) {
1774 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1775 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001776 const FieldDecl *get() const {
1777 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001778 }
1779 SourceLocation getLoc() const {
1780 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1781 }
1782};
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001783class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001784 VisitorWorkList &WL;
1785 CXCursor Parent;
1786public:
1787 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1788 : WL(wl), Parent(parent) {}
1789
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001790 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1791 void VisitBlockExpr(const BlockExpr *B);
1792 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1793 void VisitCompoundStmt(const CompoundStmt *S);
1794 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1795 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1796 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1797 void VisitCXXNewExpr(const CXXNewExpr *E);
1798 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1799 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1800 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1801 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1802 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1803 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1804 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1805 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1806 void VisitDeclRefExpr(const DeclRefExpr *D);
1807 void VisitDeclStmt(const DeclStmt *S);
1808 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1809 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1810 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1811 void VisitForStmt(const ForStmt *FS);
1812 void VisitGotoStmt(const GotoStmt *GS);
1813 void VisitIfStmt(const IfStmt *If);
1814 void VisitInitListExpr(const InitListExpr *IE);
1815 void VisitMemberExpr(const MemberExpr *M);
1816 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1817 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1818 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1819 void VisitOverloadExpr(const OverloadExpr *E);
1820 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1821 void VisitStmt(const Stmt *S);
1822 void VisitSwitchStmt(const SwitchStmt *S);
1823 void VisitWhileStmt(const WhileStmt *W);
1824 void VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E);
1825 void VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E);
1826 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1827 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1828 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1829 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1830 void VisitVAArgExpr(const VAArgExpr *E);
1831 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1832 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1833 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1834 void VisitLambdaExpr(const LambdaExpr *E);
1835
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001836private:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001837 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001838 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1839 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001840 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1841 void AddStmt(const Stmt *S);
1842 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001843 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001844 void EnqueueChildren(const Stmt *S);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001845};
1846} // end anonyous namespace
1847
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001848void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001849 // 'S' should always be non-null, since it comes from the
1850 // statement we are visiting.
1851 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1852}
1853
1854void
1855EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1856 if (Qualifier)
1857 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1858}
1859
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001860void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001861 if (S)
1862 WL.push_back(StmtVisit(S, Parent));
1863}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001864void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001865 if (D)
1866 WL.push_back(DeclVisit(D, Parent, isFirst));
1867}
1868void EnqueueVisitor::
1869 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1870 if (A)
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001871 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001872}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001873void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001874 if (D)
1875 WL.push_back(MemberRefVisit(D, L, Parent));
1876}
1877void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1878 if (TI)
1879 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1880 }
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001881void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001882 unsigned size = WL.size();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001883 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001884 AddStmt(*Child);
1885 }
1886 if (size == WL.size())
1887 return;
1888 // Now reverse the entries we just added. This will match the DFS
1889 // ordering performed by the worklist.
1890 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1891 std::reverse(I, E);
1892}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001893void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001894 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1895}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001896void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001897 AddDecl(B->getBlockDecl());
1898}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001899void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001900 EnqueueChildren(E);
1901 AddTypeLoc(E->getTypeSourceInfo());
1902}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001903void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1904 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001905 E = S->body_rend(); I != E; ++I) {
1906 AddStmt(*I);
1907 }
1908}
1909void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001910VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001911 AddStmt(S->getSubStmt());
1912 AddDeclarationNameInfo(S);
1913 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1914 AddNestedNameSpecifierLoc(QualifierLoc);
1915}
1916
1917void EnqueueVisitor::
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001918VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001919 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1920 AddDeclarationNameInfo(E);
1921 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1922 AddNestedNameSpecifierLoc(QualifierLoc);
1923 if (!E->isImplicitAccess())
1924 AddStmt(E->getBase());
1925}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001926void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001927 // Enqueue the initializer , if any.
1928 AddStmt(E->getInitializer());
1929 // Enqueue the array size, if any.
1930 AddStmt(E->getArraySize());
1931 // Enqueue the allocated type.
1932 AddTypeLoc(E->getAllocatedTypeSourceInfo());
1933 // Enqueue the placement arguments.
1934 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
1935 AddStmt(E->getPlacementArg(I-1));
1936}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001937void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001938 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
1939 AddStmt(CE->getArg(I-1));
1940 AddStmt(CE->getCallee());
1941 AddStmt(CE->getArg(0));
1942}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001943void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
1944 const CXXPseudoDestructorExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001945 // Visit the name of the type being destroyed.
1946 AddTypeLoc(E->getDestroyedTypeInfo());
1947 // Visit the scope type that looks disturbingly like the nested-name-specifier
1948 // but isn't.
1949 AddTypeLoc(E->getScopeTypeInfo());
1950 // Visit the nested-name-specifier.
1951 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1952 AddNestedNameSpecifierLoc(QualifierLoc);
1953 // Visit base expression.
1954 AddStmt(E->getBase());
1955}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001956void EnqueueVisitor::VisitCXXScalarValueInitExpr(
1957 const CXXScalarValueInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001958 AddTypeLoc(E->getTypeSourceInfo());
1959}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001960void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
1961 const CXXTemporaryObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001962 EnqueueChildren(E);
1963 AddTypeLoc(E->getTypeSourceInfo());
1964}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001965void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001966 EnqueueChildren(E);
1967 if (E->isTypeOperand())
1968 AddTypeLoc(E->getTypeOperandSourceInfo());
1969}
1970
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001971void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
1972 const CXXUnresolvedConstructExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001973 EnqueueChildren(E);
1974 AddTypeLoc(E->getTypeSourceInfo());
1975}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001976void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001977 EnqueueChildren(E);
1978 if (E->isTypeOperand())
1979 AddTypeLoc(E->getTypeOperandSourceInfo());
1980}
1981
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001982void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001983 EnqueueChildren(S);
1984 AddDecl(S->getExceptionDecl());
1985}
1986
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001987void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001988 if (DR->hasExplicitTemplateArgs()) {
1989 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
1990 }
1991 WL.push_back(DeclRefExprParts(DR, Parent));
1992}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001993void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
1994 const DependentScopeDeclRefExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00001995 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1996 AddDeclarationNameInfo(E);
1997 AddNestedNameSpecifierLoc(E->getQualifierLoc());
1998}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00001999void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002000 unsigned size = WL.size();
2001 bool isFirst = true;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002002 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002003 D != DEnd; ++D) {
2004 AddDecl(*D, isFirst);
2005 isFirst = false;
2006 }
2007 if (size == WL.size())
2008 return;
2009 // Now reverse the entries we just added. This will match the DFS
2010 // ordering performed by the worklist.
2011 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2012 std::reverse(I, E);
2013}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002014void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002015 AddStmt(E->getInit());
2016 typedef DesignatedInitExpr::Designator Designator;
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002017 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002018 D = E->designators_rbegin(), DEnd = E->designators_rend();
2019 D != DEnd; ++D) {
2020 if (D->isFieldDesignator()) {
2021 if (FieldDecl *Field = D->getField())
2022 AddMemberRef(Field, D->getFieldLoc());
2023 continue;
2024 }
2025 if (D->isArrayDesignator()) {
2026 AddStmt(E->getArrayIndex(*D));
2027 continue;
2028 }
2029 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2030 AddStmt(E->getArrayRangeEnd(*D));
2031 AddStmt(E->getArrayRangeStart(*D));
2032 }
2033}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002034void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002035 EnqueueChildren(E);
2036 AddTypeLoc(E->getTypeInfoAsWritten());
2037}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002038void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002039 AddStmt(FS->getBody());
2040 AddStmt(FS->getInc());
2041 AddStmt(FS->getCond());
2042 AddDecl(FS->getConditionVariable());
2043 AddStmt(FS->getInit());
2044}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002045void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002046 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2047}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002048void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002049 AddStmt(If->getElse());
2050 AddStmt(If->getThen());
2051 AddStmt(If->getCond());
2052 AddDecl(If->getConditionVariable());
2053}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002054void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002055 // We care about the syntactic form of the initializer list, only.
2056 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2057 IE = Syntactic;
2058 EnqueueChildren(IE);
2059}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002060void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002061 WL.push_back(MemberExprParts(M, Parent));
2062
2063 // If the base of the member access expression is an implicit 'this', don't
2064 // visit it.
2065 // FIXME: If we ever want to show these implicit accesses, this will be
2066 // unfortunate. However, clang_getCursor() relies on this behavior.
2067 if (!M->isImplicitAccess())
2068 AddStmt(M->getBase());
2069}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002070void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002071 AddTypeLoc(E->getEncodedTypeSourceInfo());
2072}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002073void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002074 EnqueueChildren(M);
2075 AddTypeLoc(M->getClassReceiverTypeInfo());
2076}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002077void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002078 // Visit the components of the offsetof expression.
2079 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2080 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2081 const OffsetOfNode &Node = E->getComponent(I-1);
2082 switch (Node.getKind()) {
2083 case OffsetOfNode::Array:
2084 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2085 break;
2086 case OffsetOfNode::Field:
2087 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2088 break;
2089 case OffsetOfNode::Identifier:
2090 case OffsetOfNode::Base:
2091 continue;
2092 }
2093 }
2094 // Visit the type into which we're computing the offset.
2095 AddTypeLoc(E->getTypeSourceInfo());
2096}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002097void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002098 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2099 WL.push_back(OverloadExprParts(E, Parent));
2100}
2101void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002102 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002103 EnqueueChildren(E);
2104 if (E->isArgumentType())
2105 AddTypeLoc(E->getArgumentTypeInfo());
2106}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002107void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002108 EnqueueChildren(S);
2109}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002110void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002111 AddStmt(S->getBody());
2112 AddStmt(S->getCond());
2113 AddDecl(S->getConditionVariable());
2114}
2115
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002116void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002117 AddStmt(W->getBody());
2118 AddStmt(W->getCond());
2119 AddDecl(W->getConditionVariable());
2120}
2121
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002122void EnqueueVisitor::VisitUnaryTypeTraitExpr(const UnaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002123 AddTypeLoc(E->getQueriedTypeSourceInfo());
2124}
2125
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002126void EnqueueVisitor::VisitBinaryTypeTraitExpr(const BinaryTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002127 AddTypeLoc(E->getRhsTypeSourceInfo());
2128 AddTypeLoc(E->getLhsTypeSourceInfo());
2129}
2130
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002131void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002132 for (unsigned I = E->getNumArgs(); I > 0; --I)
2133 AddTypeLoc(E->getArg(I-1));
2134}
2135
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002136void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002137 AddTypeLoc(E->getQueriedTypeSourceInfo());
2138}
2139
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002140void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002141 EnqueueChildren(E);
2142}
2143
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002144void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002145 VisitOverloadExpr(U);
2146 if (!U->isImplicitAccess())
2147 AddStmt(U->getBase());
2148}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002149void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002150 AddStmt(E->getSubExpr());
2151 AddTypeLoc(E->getWrittenTypeInfo());
2152}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002153void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002154 WL.push_back(SizeOfPackExprParts(E, Parent));
2155}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002156void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002157 // If the opaque value has a source expression, just transparently
2158 // visit that. This is useful for (e.g.) pseudo-object expressions.
2159 if (Expr *SourceExpr = E->getSourceExpr())
2160 return Visit(SourceExpr);
2161}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002162void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002163 AddStmt(E->getBody());
2164 WL.push_back(LambdaExprParts(E, Parent));
2165}
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002166void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002167 // Treat the expression like its syntactic form.
2168 Visit(E->getSyntacticForm());
2169}
2170
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002171void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002172 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2173}
2174
2175bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2176 if (RegionOfInterest.isValid()) {
2177 SourceRange Range = getRawCursorExtent(C);
2178 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2179 return false;
2180 }
2181 return true;
2182}
2183
2184bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2185 while (!WL.empty()) {
2186 // Dequeue the worklist item.
2187 VisitorJob LI = WL.back();
2188 WL.pop_back();
2189
2190 // Set the Parent field, then back to its old value once we're done.
2191 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2192
2193 switch (LI.getKind()) {
2194 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002195 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002196 if (!D)
2197 continue;
2198
2199 // For now, perform default visitation for Decls.
2200 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2201 cast<DeclVisit>(&LI)->isFirst())))
2202 return true;
2203
2204 continue;
2205 }
2206 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2207 const ASTTemplateArgumentListInfo *ArgList =
2208 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2209 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2210 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2211 Arg != ArgEnd; ++Arg) {
2212 if (VisitTemplateArgumentLoc(*Arg))
2213 return true;
2214 }
2215 continue;
2216 }
2217 case VisitorJob::TypeLocVisitKind: {
2218 // Perform default visitation for TypeLocs.
2219 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2220 return true;
2221 continue;
2222 }
2223 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002224 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002225 if (LabelStmt *stmt = LS->getStmt()) {
2226 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2227 TU))) {
2228 return true;
2229 }
2230 }
2231 continue;
2232 }
2233
2234 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2235 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2236 if (VisitNestedNameSpecifierLoc(V->get()))
2237 return true;
2238 continue;
2239 }
2240
2241 case VisitorJob::DeclarationNameInfoVisitKind: {
2242 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2243 ->get()))
2244 return true;
2245 continue;
2246 }
2247 case VisitorJob::MemberRefVisitKind: {
2248 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2249 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2250 return true;
2251 continue;
2252 }
2253 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002254 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002255 if (!S)
2256 continue;
2257
2258 // Update the current cursor.
2259 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2260 if (!IsInRegionOfInterest(Cursor))
2261 continue;
2262 switch (Visitor(Cursor, Parent, ClientData)) {
2263 case CXChildVisit_Break: return true;
2264 case CXChildVisit_Continue: break;
2265 case CXChildVisit_Recurse:
2266 if (PostChildrenVisitor)
2267 WL.push_back(PostChildrenVisit(0, Cursor));
2268 EnqueueWorkList(WL, S);
2269 break;
2270 }
2271 continue;
2272 }
2273 case VisitorJob::MemberExprPartsKind: {
2274 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002275 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002276
2277 // Visit the nested-name-specifier
2278 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2279 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2280 return true;
2281
2282 // Visit the declaration name.
2283 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2284 return true;
2285
2286 // Visit the explicitly-specified template arguments, if any.
2287 if (M->hasExplicitTemplateArgs()) {
2288 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2289 *ArgEnd = Arg + M->getNumTemplateArgs();
2290 Arg != ArgEnd; ++Arg) {
2291 if (VisitTemplateArgumentLoc(*Arg))
2292 return true;
2293 }
2294 }
2295 continue;
2296 }
2297 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002298 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002299 // Visit nested-name-specifier, if present.
2300 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2301 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2302 return true;
2303 // Visit declaration name.
2304 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2305 return true;
2306 continue;
2307 }
2308 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002309 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002310 // Visit the nested-name-specifier.
2311 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2312 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2313 return true;
2314 // Visit the declaration name.
2315 if (VisitDeclarationNameInfo(O->getNameInfo()))
2316 return true;
2317 // Visit the overloaded declaration reference.
2318 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2319 return true;
2320 continue;
2321 }
2322 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002323 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002324 NamedDecl *Pack = E->getPack();
2325 if (isa<TemplateTypeParmDecl>(Pack)) {
2326 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2327 E->getPackLoc(), TU)))
2328 return true;
2329
2330 continue;
2331 }
2332
2333 if (isa<TemplateTemplateParmDecl>(Pack)) {
2334 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2335 E->getPackLoc(), TU)))
2336 return true;
2337
2338 continue;
2339 }
2340
2341 // Non-type template parameter packs and function parameter packs are
2342 // treated like DeclRefExpr cursors.
2343 continue;
2344 }
2345
2346 case VisitorJob::LambdaExprPartsKind: {
2347 // Visit captures.
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002348 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002349 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2350 CEnd = E->explicit_capture_end();
2351 C != CEnd; ++C) {
2352 if (C->capturesThis())
2353 continue;
2354
2355 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2356 C->getLocation(),
2357 TU)))
2358 return true;
2359 }
2360
2361 // Visit parameters and return type, if present.
2362 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2363 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2364 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2365 // Visit the whole type.
2366 if (Visit(TL))
2367 return true;
David Blaikie39e6ab42013-02-18 22:06:02 +00002368 } else if (FunctionProtoTypeLoc Proto =
2369 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002370 if (E->hasExplicitParameters()) {
2371 // Visit parameters.
2372 for (unsigned I = 0, N = Proto.getNumArgs(); I != N; ++I)
2373 if (Visit(MakeCXCursor(Proto.getArg(I), TU)))
2374 return true;
2375 } else {
2376 // Visit result type.
2377 if (Visit(Proto.getResultLoc()))
2378 return true;
2379 }
2380 }
2381 }
2382 break;
2383 }
2384
2385 case VisitorJob::PostChildrenVisitKind:
2386 if (PostChildrenVisitor(Parent, ClientData))
2387 return true;
2388 break;
2389 }
2390 }
2391 return false;
2392}
2393
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00002394bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002395 VisitorWorkList *WL = 0;
2396 if (!WorkListFreeList.empty()) {
2397 WL = WorkListFreeList.back();
2398 WL->clear();
2399 WorkListFreeList.pop_back();
2400 }
2401 else {
2402 WL = new VisitorWorkList();
2403 WorkListCache.push_back(WL);
2404 }
2405 EnqueueWorkList(*WL, S);
2406 bool result = RunVisitorWorkList(*WL);
2407 WorkListFreeList.push_back(WL);
2408 return result;
2409}
2410
2411namespace {
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00002412typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002413RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2414 const DeclarationNameInfo &NI,
2415 const SourceRange &QLoc,
2416 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2417 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2418 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2419 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2420
2421 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2422
2423 RefNamePieces Pieces;
2424
2425 if (WantQualifier && QLoc.isValid())
2426 Pieces.push_back(QLoc);
2427
2428 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2429 Pieces.push_back(NI.getLoc());
2430
2431 if (WantTemplateArgs && TemplateArgs)
2432 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2433 TemplateArgs->RAngleLoc));
2434
2435 if (Kind == DeclarationName::CXXOperatorName) {
2436 Pieces.push_back(SourceLocation::getFromRawEncoding(
2437 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2438 Pieces.push_back(SourceLocation::getFromRawEncoding(
2439 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2440 }
2441
2442 if (WantSinglePiece) {
2443 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2444 Pieces.clear();
2445 Pieces.push_back(R);
2446 }
2447
2448 return Pieces;
2449}
2450}
2451
2452//===----------------------------------------------------------------------===//
2453// Misc. API hooks.
2454//===----------------------------------------------------------------------===//
2455
2456static llvm::sys::Mutex EnableMultithreadingMutex;
2457static bool EnabledMultithreading;
2458
Chad Rosier90836282013-03-27 18:28:23 +00002459static void fatal_error_handler(void *user_data, const std::string& reason,
2460 bool gen_crash_diag) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002461 // Write the result out to stderr avoiding errs() because raw_ostreams can
2462 // call report_fatal_error.
2463 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2464 ::abort();
2465}
2466
2467extern "C" {
2468CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2469 int displayDiagnostics) {
2470 // Disable pretty stack trace functionality, which will otherwise be a very
2471 // poor citizen of the world and set up all sorts of signal handlers.
2472 llvm::DisablePrettyStackTrace = true;
2473
2474 // We use crash recovery to make some of our APIs more reliable, implicitly
2475 // enable it.
2476 llvm::CrashRecoveryContext::Enable();
2477
2478 // Enable support for multithreading in LLVM.
2479 {
2480 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2481 if (!EnabledMultithreading) {
2482 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2483 llvm::llvm_start_multithreaded();
2484 EnabledMultithreading = true;
2485 }
2486 }
2487
2488 CIndexer *CIdxr = new CIndexer();
2489 if (excludeDeclarationsFromPCH)
2490 CIdxr->setOnlyLocalDecls();
2491 if (displayDiagnostics)
2492 CIdxr->setDisplayDiagnostics();
2493
2494 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2495 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2496 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2497 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2498 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2499 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2500
2501 return CIdxr;
2502}
2503
2504void clang_disposeIndex(CXIndex CIdx) {
2505 if (CIdx)
2506 delete static_cast<CIndexer *>(CIdx);
2507}
2508
2509void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2510 if (CIdx)
2511 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2512}
2513
2514unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2515 if (CIdx)
2516 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2517 return 0;
2518}
2519
2520void clang_toggleCrashRecovery(unsigned isEnabled) {
2521 if (isEnabled)
2522 llvm::CrashRecoveryContext::Enable();
2523 else
2524 llvm::CrashRecoveryContext::Disable();
2525}
2526
2527CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2528 const char *ast_filename) {
2529 if (!CIdx)
2530 return 0;
2531
2532 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2533 FileSystemOptions FileSystemOpts;
2534
2535 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
2536 ASTUnit *TU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
2537 CXXIdx->getOnlyLocalDecls(),
2538 0, 0,
2539 /*CaptureDiagnostics=*/true,
2540 /*AllowPCHWithCompilerErrors=*/true,
2541 /*UserFilesAreVolatile=*/true);
2542 return MakeCXTranslationUnit(CXXIdx, TU);
2543}
2544
2545unsigned clang_defaultEditingTranslationUnitOptions() {
2546 return CXTranslationUnit_PrecompiledPreamble |
2547 CXTranslationUnit_CacheCompletionResults;
2548}
2549
2550CXTranslationUnit
2551clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2552 const char *source_filename,
2553 int num_command_line_args,
2554 const char * const *command_line_args,
2555 unsigned num_unsaved_files,
2556 struct CXUnsavedFile *unsaved_files) {
2557 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2558 return clang_parseTranslationUnit(CIdx, source_filename,
2559 command_line_args, num_command_line_args,
2560 unsaved_files, num_unsaved_files,
2561 Options);
2562}
2563
2564struct ParseTranslationUnitInfo {
2565 CXIndex CIdx;
2566 const char *source_filename;
2567 const char *const *command_line_args;
2568 int num_command_line_args;
2569 struct CXUnsavedFile *unsaved_files;
2570 unsigned num_unsaved_files;
2571 unsigned options;
2572 CXTranslationUnit result;
2573};
2574static void clang_parseTranslationUnit_Impl(void *UserData) {
2575 ParseTranslationUnitInfo *PTUI =
2576 static_cast<ParseTranslationUnitInfo*>(UserData);
2577 CXIndex CIdx = PTUI->CIdx;
2578 const char *source_filename = PTUI->source_filename;
2579 const char * const *command_line_args = PTUI->command_line_args;
2580 int num_command_line_args = PTUI->num_command_line_args;
2581 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2582 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2583 unsigned options = PTUI->options;
2584 PTUI->result = 0;
2585
2586 if (!CIdx)
2587 return;
2588
2589 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2590
2591 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2592 setThreadBackgroundPriority();
2593
2594 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2595 // FIXME: Add a flag for modules.
2596 TranslationUnitKind TUKind
2597 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
2598 bool CacheCodeCompetionResults
2599 = options & CXTranslationUnit_CacheCompletionResults;
2600 bool IncludeBriefCommentsInCodeCompletion
2601 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2602 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2603 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2604
2605 // Configure the diagnostics.
2606 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvad47afb92013-01-20 01:58:28 +00002607 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002608
2609 // Recover resources if we crash before exiting this function.
2610 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2611 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2612 DiagCleanup(Diags.getPtr());
2613
2614 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2615 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2616
2617 // Recover resources if we crash before exiting this function.
2618 llvm::CrashRecoveryContextCleanupRegistrar<
2619 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2620
2621 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2622 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2623 const llvm::MemoryBuffer *Buffer
2624 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2625 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2626 Buffer));
2627 }
2628
2629 OwningPtr<std::vector<const char *> >
2630 Args(new std::vector<const char*>());
2631
2632 // Recover resources if we crash before exiting this method.
2633 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2634 ArgsCleanup(Args.get());
2635
2636 // Since the Clang C library is primarily used by batch tools dealing with
2637 // (often very broken) source code, where spell-checking can have a
2638 // significant negative impact on performance (particularly when
2639 // precompiled headers are involved), we disable it by default.
2640 // Only do this if we haven't found a spell-checking-related argument.
2641 bool FoundSpellCheckingArgument = false;
2642 for (int I = 0; I != num_command_line_args; ++I) {
2643 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2644 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2645 FoundSpellCheckingArgument = true;
2646 break;
2647 }
2648 }
2649 if (!FoundSpellCheckingArgument)
2650 Args->push_back("-fno-spell-checking");
2651
2652 Args->insert(Args->end(), command_line_args,
2653 command_line_args + num_command_line_args);
2654
2655 // The 'source_filename' argument is optional. If the caller does not
2656 // specify it then it is assumed that the source file is specified
2657 // in the actual argument list.
2658 // Put the source file after command_line_args otherwise if '-x' flag is
2659 // present it will be unused.
2660 if (source_filename)
2661 Args->push_back(source_filename);
2662
2663 // Do we need the detailed preprocessing record?
2664 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2665 Args->push_back("-Xclang");
2666 Args->push_back("-detailed-preprocessing-record");
2667 }
2668
2669 unsigned NumErrors = Diags->getClient()->getNumErrors();
2670 OwningPtr<ASTUnit> ErrUnit;
2671 OwningPtr<ASTUnit> Unit(
2672 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2673 /* vector::data() not portable */,
2674 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2675 Diags,
2676 CXXIdx->getClangResourcesPath(),
2677 CXXIdx->getOnlyLocalDecls(),
2678 /*CaptureDiagnostics=*/true,
2679 RemappedFiles->size() ? &(*RemappedFiles)[0]:0,
2680 RemappedFiles->size(),
2681 /*RemappedFilesKeepOriginalName=*/true,
2682 PrecompilePreamble,
2683 TUKind,
2684 CacheCodeCompetionResults,
2685 IncludeBriefCommentsInCodeCompletion,
2686 /*AllowPCHWithCompilerErrors=*/true,
2687 SkipFunctionBodies,
2688 /*UserFilesAreVolatile=*/true,
2689 ForSerialization,
2690 &ErrUnit));
2691
2692 if (NumErrors != Diags->getClient()->getNumErrors()) {
2693 // Make sure to check that 'Unit' is non-NULL.
2694 if (CXXIdx->getDisplayDiagnostics())
2695 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2696 }
2697
2698 PTUI->result = MakeCXTranslationUnit(CXXIdx, Unit.take());
2699}
2700CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,
2701 const char *source_filename,
2702 const char * const *command_line_args,
2703 int num_command_line_args,
2704 struct CXUnsavedFile *unsaved_files,
2705 unsigned num_unsaved_files,
2706 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002707 LOG_FUNC_SECTION {
2708 *Log << source_filename << ": ";
2709 for (int i = 0; i != num_command_line_args; ++i)
2710 *Log << command_line_args[i] << " ";
2711 }
2712
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002713 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2714 num_command_line_args, unsaved_files,
2715 num_unsaved_files, options, 0 };
2716 llvm::CrashRecoveryContext CRC;
2717
2718 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2719 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2720 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2721 fprintf(stderr, " 'command_line_args' : [");
2722 for (int i = 0; i != num_command_line_args; ++i) {
2723 if (i)
2724 fprintf(stderr, ", ");
2725 fprintf(stderr, "'%s'", command_line_args[i]);
2726 }
2727 fprintf(stderr, "],\n");
2728 fprintf(stderr, " 'unsaved_files' : [");
2729 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2730 if (i)
2731 fprintf(stderr, ", ");
2732 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2733 unsaved_files[i].Length);
2734 }
2735 fprintf(stderr, "],\n");
2736 fprintf(stderr, " 'options' : %d,\n", options);
2737 fprintf(stderr, "}\n");
2738
2739 return 0;
2740 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2741 PrintLibclangResourceUsage(PTUI.result);
2742 }
2743
2744 return PTUI.result;
2745}
2746
2747unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2748 return CXSaveTranslationUnit_None;
2749}
2750
2751namespace {
2752
2753struct SaveTranslationUnitInfo {
2754 CXTranslationUnit TU;
2755 const char *FileName;
2756 unsigned options;
2757 CXSaveError result;
2758};
2759
2760}
2761
2762static void clang_saveTranslationUnit_Impl(void *UserData) {
2763 SaveTranslationUnitInfo *STUI =
2764 static_cast<SaveTranslationUnitInfo*>(UserData);
2765
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002766 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002767 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2768 setThreadBackgroundPriority();
2769
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002770 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002771 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2772}
2773
2774int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2775 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002776 LOG_FUNC_SECTION {
2777 *Log << TU << ' ' << FileName;
2778 }
2779
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002780 if (!TU)
2781 return CXSaveError_InvalidTU;
2782
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002783 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002784 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2785 if (!CXXUnit->hasSema())
2786 return CXSaveError_InvalidTU;
2787
2788 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2789
2790 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2791 getenv("LIBCLANG_NOTHREADS")) {
2792 clang_saveTranslationUnit_Impl(&STUI);
2793
2794 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2795 PrintLibclangResourceUsage(TU);
2796
2797 return STUI.result;
2798 }
2799
2800 // We have an AST that has invalid nodes due to compiler errors.
2801 // Use a crash recovery thread for protection.
2802
2803 llvm::CrashRecoveryContext CRC;
2804
2805 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2806 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2807 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2808 fprintf(stderr, " 'options' : %d,\n", options);
2809 fprintf(stderr, "}\n");
2810
2811 return CXSaveError_Unknown;
2812
2813 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2814 PrintLibclangResourceUsage(TU);
2815 }
2816
2817 return STUI.result;
2818}
2819
2820void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2821 if (CTUnit) {
2822 // If the translation unit has been marked as unsafe to free, just discard
2823 // it.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002824 if (cxtu::getASTUnit(CTUnit)->isUnsafeToFree())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002825 return;
2826
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002827 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenko9c48d162013-01-26 22:44:19 +00002828 delete CTUnit->StringPool;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002829 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2830 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko337ee242013-01-26 21:39:50 +00002831 delete CTUnit->FormatContext;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002832 delete CTUnit;
2833 }
2834}
2835
2836unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2837 return CXReparse_None;
2838}
2839
2840struct ReparseTranslationUnitInfo {
2841 CXTranslationUnit TU;
2842 unsigned num_unsaved_files;
2843 struct CXUnsavedFile *unsaved_files;
2844 unsigned options;
2845 int result;
2846};
2847
2848static void clang_reparseTranslationUnit_Impl(void *UserData) {
2849 ReparseTranslationUnitInfo *RTUI =
2850 static_cast<ReparseTranslationUnitInfo*>(UserData);
2851 CXTranslationUnit TU = RTUI->TU;
Argyrios Kyrtzidisd7bf4a42013-01-16 18:13:00 +00002852 if (!TU)
2853 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002854
2855 // Reset the associated diagnostics.
2856 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2857 TU->Diagnostics = 0;
2858
2859 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2860 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2861 unsigned options = RTUI->options;
2862 (void) options;
2863 RTUI->result = 1;
2864
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00002865 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002866 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
2867 setThreadBackgroundPriority();
2868
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002869 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002870 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2871
2872 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2873 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2874
2875 // Recover resources if we crash before exiting this function.
2876 llvm::CrashRecoveryContextCleanupRegistrar<
2877 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2878
2879 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2880 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2881 const llvm::MemoryBuffer *Buffer
2882 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2883 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2884 Buffer));
2885 }
2886
2887 if (!CXXUnit->Reparse(RemappedFiles->size() ? &(*RemappedFiles)[0] : 0,
2888 RemappedFiles->size()))
2889 RTUI->result = 0;
2890}
2891
2892int clang_reparseTranslationUnit(CXTranslationUnit TU,
2893 unsigned num_unsaved_files,
2894 struct CXUnsavedFile *unsaved_files,
2895 unsigned options) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00002896 LOG_FUNC_SECTION {
2897 *Log << TU;
2898 }
2899
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002900 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
2901 options, 0 };
2902
2903 if (getenv("LIBCLANG_NOTHREADS")) {
2904 clang_reparseTranslationUnit_Impl(&RTUI);
2905 return RTUI.result;
2906 }
2907
2908 llvm::CrashRecoveryContext CRC;
2909
2910 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
2911 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002912 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002913 return 1;
2914 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
2915 PrintLibclangResourceUsage(TU);
2916
2917 return RTUI.result;
2918}
2919
2920
2921CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
2922 if (!CTUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00002923 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002924
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002925 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00002926 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002927}
2928
2929CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00002930 if (!TU)
2931 return clang_getNullCursor();
2932
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002933 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002934 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
2935}
2936
2937} // end: extern "C"
2938
2939//===----------------------------------------------------------------------===//
2940// CXFile Operations.
2941//===----------------------------------------------------------------------===//
2942
2943extern "C" {
2944CXString clang_getFileName(CXFile SFile) {
2945 if (!SFile)
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00002946 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002947
2948 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00002949 return cxstring::createRef(FEnt->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002950}
2951
2952time_t clang_getFileTime(CXFile SFile) {
2953 if (!SFile)
2954 return 0;
2955
2956 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
2957 return FEnt->getModificationTime();
2958}
2959
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002960CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
2961 if (!TU)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002962 return 0;
2963
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002964 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002965
2966 FileManager &FMgr = CXXUnit->getFileManager();
2967 return const_cast<FileEntry *>(FMgr.getFile(file_name));
2968}
2969
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002970unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
2971 if (!TU || !file)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002972 return 0;
2973
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00002974 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002975 FileEntry *FEnt = static_cast<FileEntry *>(file);
2976 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
2977 .isFileMultipleIncludeGuarded(FEnt);
2978}
2979
Argyrios Kyrtzidisdb84e7a2013-01-26 04:52:52 +00002980int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
2981 if (!file || !outID)
2982 return 1;
2983
2984#ifdef LLVM_ON_WIN32
2985 return 1; // inodes not supported on windows.
2986#else
2987 FileEntry *FEnt = static_cast<FileEntry *>(file);
2988 outID->data[0] = FEnt->getDevice();
2989 outID->data[1] = FEnt->getInode();
2990 outID->data[2] = FEnt->getModificationTime();
2991 return 0;
2992#endif
2993}
2994
Guy Benyei7f92f2d2012-12-18 14:30:41 +00002995} // end: extern "C"
2996
2997//===----------------------------------------------------------------------===//
2998// CXCursor Operations.
2999//===----------------------------------------------------------------------===//
3000
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003001static const Decl *getDeclFromExpr(const Stmt *E) {
3002 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003003 return getDeclFromExpr(CE->getSubExpr());
3004
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003005 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003006 return RefExpr->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003007 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003008 return ME->getMemberDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003009 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003010 return RE->getDecl();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003011 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003012 if (PRE->isExplicitProperty())
3013 return PRE->getExplicitProperty();
3014 // It could be messaging both getter and setter as in:
3015 // ++myobj.myprop;
3016 // in which case prefer to associate the setter since it is less obvious
3017 // from inspecting the source that the setter is going to get called.
3018 if (PRE->isMessagingSetter())
3019 return PRE->getImplicitPropertySetter();
3020 return PRE->getImplicitPropertyGetter();
3021 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003022 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003023 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003024 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003025 if (Expr *Src = OVE->getSourceExpr())
3026 return getDeclFromExpr(Src);
3027
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003028 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003029 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003030 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003031 if (!CE->isElidable())
3032 return CE->getConstructor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003033 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003034 return OME->getMethodDecl();
3035
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003036 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003037 return PE->getProtocol();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003038 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003039 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3040 return NTTP->getParameterPack();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003041 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003042 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3043 isa<ParmVarDecl>(SizeOfPack->getPack()))
3044 return SizeOfPack->getPack();
3045
3046 return 0;
3047}
3048
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003049static SourceLocation getLocationFromExpr(const Expr *E) {
3050 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003051 return getLocationFromExpr(CE->getSubExpr());
3052
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003053 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003054 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003055 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003056 return DRE->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003057 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003058 return Member->getMemberLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003059 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003060 return Ivar->getLocation();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003061 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003062 return SizeOfPack->getPackLoc();
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003063 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003064 return PropRef->getLocation();
3065
3066 return E->getLocStart();
3067}
3068
3069extern "C" {
3070
3071unsigned clang_visitChildren(CXCursor parent,
3072 CXCursorVisitor visitor,
3073 CXClientData client_data) {
3074 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3075 /*VisitPreprocessorLast=*/false);
3076 return CursorVis.VisitChildren(parent);
3077}
3078
3079#ifndef __has_feature
3080#define __has_feature(x) 0
3081#endif
3082#if __has_feature(blocks)
3083typedef enum CXChildVisitResult
3084 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3085
3086static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3087 CXClientData client_data) {
3088 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3089 return block(cursor, parent);
3090}
3091#else
3092// If we are compiled with a compiler that doesn't have native blocks support,
3093// define and call the block manually, so the
3094typedef struct _CXChildVisitResult
3095{
3096 void *isa;
3097 int flags;
3098 int reserved;
3099 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3100 CXCursor);
3101} *CXCursorVisitorBlock;
3102
3103static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3104 CXClientData client_data) {
3105 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3106 return block->invoke(block, cursor, parent);
3107}
3108#endif
3109
3110
3111unsigned clang_visitChildrenWithBlock(CXCursor parent,
3112 CXCursorVisitorBlock block) {
3113 return clang_visitChildren(parent, visitWithBlock, block);
3114}
3115
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003116static CXString getDeclSpelling(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003117 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003118 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003119
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003120 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003121 if (!ND) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003122 if (const ObjCPropertyImplDecl *PropImpl =
3123 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003124 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003125 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003126
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003127 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003128 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003129 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003130
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003131 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003132 }
3133
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003134 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003135 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003136
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003137 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003138 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3139 // and returns different names. NamedDecl returns the class name and
3140 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003141 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003142
3143 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003144 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003145
3146 SmallString<1024> S;
3147 llvm::raw_svector_ostream os(S);
3148 ND->printName(os);
3149
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003150 return cxstring::createDup(os.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003151}
3152
3153CXString clang_getCursorSpelling(CXCursor C) {
3154 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko46f92522013-01-11 19:28:44 +00003155 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003156
3157 if (clang_isReference(C.kind)) {
3158 switch (C.kind) {
3159 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003160 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003161 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003162 }
3163 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003164 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003165 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003166 }
3167 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003168 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003169 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003170 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003171 }
3172 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003173 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003174 return cxstring::createDup(B->getType().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003175 }
3176 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003177 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003178 assert(Type && "Missing type decl");
3179
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003180 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003181 getAsString());
3182 }
3183 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003184 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003185 assert(Template && "Missing template decl");
3186
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003187 return cxstring::createDup(Template->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003188 }
3189
3190 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003191 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003192 assert(NS && "Missing namespace decl");
3193
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003194 return cxstring::createDup(NS->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003195 }
3196
3197 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003198 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003199 assert(Field && "Missing member decl");
3200
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003201 return cxstring::createDup(Field->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003202 }
3203
3204 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003205 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003206 assert(Label && "Missing label");
3207
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003208 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003209 }
3210
3211 case CXCursor_OverloadedDeclRef: {
3212 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003213 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3214 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003215 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003216 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003217 }
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003218 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003219 return cxstring::createDup(E->getName().getAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003220 OverloadedTemplateStorage *Ovl
3221 = Storage.get<OverloadedTemplateStorage*>();
3222 if (Ovl->size() == 0)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003223 return cxstring::createEmpty();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003224 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003225 }
3226
3227 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003228 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003229 assert(Var && "Missing variable decl");
3230
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003231 return cxstring::createDup(Var->getNameAsString());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003232 }
3233
3234 default:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003235 return cxstring::createRef("<not implemented>");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003236 }
3237 }
3238
3239 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003240 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003241 if (D)
3242 return getDeclSpelling(D);
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003243 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003244 }
3245
3246 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003247 const Stmt *S = getCursorStmt(C);
3248 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003249 return cxstring::createRef(Label->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003250
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003251 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003252 }
3253
3254 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003255 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003256 ->getNameStart());
3257
3258 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003259 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003260 ->getNameStart());
3261
3262 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003263 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003264
3265 if (clang_isDeclaration(C.kind))
3266 return getDeclSpelling(getCursorDecl(C));
3267
3268 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003269 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003270 return cxstring::createDup(AA->getAnnotation());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003271 }
3272
3273 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenko7d914382013-01-26 18:08:08 +00003274 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003275 return cxstring::createDup(AA->getLabel());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003276 }
3277
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003278 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003279}
3280
3281CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3282 unsigned pieceIndex,
3283 unsigned options) {
3284 if (clang_Cursor_isNull(C))
3285 return clang_getNullRange();
3286
3287 ASTContext &Ctx = getCursorContext(C);
3288
3289 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003290 const Stmt *S = getCursorStmt(C);
3291 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003292 if (pieceIndex > 0)
3293 return clang_getNullRange();
3294 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3295 }
3296
3297 return clang_getNullRange();
3298 }
3299
3300 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00003301 if (const ObjCMessageExpr *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003302 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3303 if (pieceIndex >= ME->getNumSelectorLocs())
3304 return clang_getNullRange();
3305 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3306 }
3307 }
3308
3309 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3310 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003311 if (const ObjCMethodDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003312 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3313 if (pieceIndex >= MD->getNumSelectorLocs())
3314 return clang_getNullRange();
3315 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3316 }
3317 }
3318
3319 if (C.kind == CXCursor_ObjCCategoryDecl ||
3320 C.kind == CXCursor_ObjCCategoryImplDecl) {
3321 if (pieceIndex > 0)
3322 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003323 if (const ObjCCategoryDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003324 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3325 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003326 if (const ObjCCategoryImplDecl *
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003327 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3328 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3329 }
3330
3331 if (C.kind == CXCursor_ModuleImportDecl) {
3332 if (pieceIndex > 0)
3333 return clang_getNullRange();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003334 if (const ImportDecl *ImportD =
3335 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003336 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3337 if (!Locs.empty())
3338 return cxloc::translateSourceRange(Ctx,
3339 SourceRange(Locs.front(), Locs.back()));
3340 }
3341 return clang_getNullRange();
3342 }
3343
3344 // FIXME: A CXCursor_InclusionDirective should give the location of the
3345 // filename, but we don't keep track of this.
3346
3347 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3348 // but we don't keep track of this.
3349
3350 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3351 // but we don't keep track of this.
3352
3353 // Default handling, give the location of the cursor.
3354
3355 if (pieceIndex > 0)
3356 return clang_getNullRange();
3357
3358 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3359 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3360 return cxloc::translateSourceRange(Ctx, Loc);
3361}
3362
3363CXString clang_getCursorDisplayName(CXCursor C) {
3364 if (!clang_isDeclaration(C.kind))
3365 return clang_getCursorSpelling(C);
3366
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003367 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003368 if (!D)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00003369 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003370
3371 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003372 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003373 D = FunTmpl->getTemplatedDecl();
3374
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003375 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003376 SmallString<64> Str;
3377 llvm::raw_svector_ostream OS(Str);
3378 OS << *Function;
3379 if (Function->getPrimaryTemplate())
3380 OS << "<>";
3381 OS << "(";
3382 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3383 if (I)
3384 OS << ", ";
3385 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3386 }
3387
3388 if (Function->isVariadic()) {
3389 if (Function->getNumParams())
3390 OS << ", ";
3391 OS << "...";
3392 }
3393 OS << ")";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003394 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003395 }
3396
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003397 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003398 SmallString<64> Str;
3399 llvm::raw_svector_ostream OS(Str);
3400 OS << *ClassTemplate;
3401 OS << "<";
3402 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3403 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3404 if (I)
3405 OS << ", ";
3406
3407 NamedDecl *Param = Params->getParam(I);
3408 if (Param->getIdentifier()) {
3409 OS << Param->getIdentifier()->getName();
3410 continue;
3411 }
3412
3413 // There is no parameter name, which makes this tricky. Try to come up
3414 // with something useful that isn't too long.
3415 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3416 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3417 else if (NonTypeTemplateParmDecl *NTTP
3418 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3419 OS << NTTP->getType().getAsString(Policy);
3420 else
3421 OS << "template<...> class";
3422 }
3423
3424 OS << ">";
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003425 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003426 }
3427
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003428 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003429 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3430 // If the type was explicitly written, use that.
3431 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003432 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003433
Benjamin Kramer5eada842013-02-22 15:46:01 +00003434 SmallString<128> Str;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003435 llvm::raw_svector_ostream OS(Str);
3436 OS << *ClassSpec;
Benjamin Kramer5eada842013-02-22 15:46:01 +00003437 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003438 ClassSpec->getTemplateArgs().data(),
3439 ClassSpec->getTemplateArgs().size(),
3440 Policy);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00003441 return cxstring::createDup(OS.str());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003442 }
3443
3444 return clang_getCursorSpelling(C);
3445}
3446
3447CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3448 switch (Kind) {
3449 case CXCursor_FunctionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003450 return cxstring::createRef("FunctionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003451 case CXCursor_TypedefDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003452 return cxstring::createRef("TypedefDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003453 case CXCursor_EnumDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003454 return cxstring::createRef("EnumDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003455 case CXCursor_EnumConstantDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003456 return cxstring::createRef("EnumConstantDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003457 case CXCursor_StructDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003458 return cxstring::createRef("StructDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003459 case CXCursor_UnionDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003460 return cxstring::createRef("UnionDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003461 case CXCursor_ClassDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003462 return cxstring::createRef("ClassDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003463 case CXCursor_FieldDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003464 return cxstring::createRef("FieldDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003465 case CXCursor_VarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003466 return cxstring::createRef("VarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003467 case CXCursor_ParmDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003468 return cxstring::createRef("ParmDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003469 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003470 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003471 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003472 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003473 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003474 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003475 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003476 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003477 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003478 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003479 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003480 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003481 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003482 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003483 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003484 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003485 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003486 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003487 case CXCursor_CXXMethod:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003488 return cxstring::createRef("CXXMethod");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003489 case CXCursor_UnexposedDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003490 return cxstring::createRef("UnexposedDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003491 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003492 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003493 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003494 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003495 case CXCursor_ObjCClassRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003496 return cxstring::createRef("ObjCClassRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003497 case CXCursor_TypeRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003498 return cxstring::createRef("TypeRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003499 case CXCursor_TemplateRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003500 return cxstring::createRef("TemplateRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003501 case CXCursor_NamespaceRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003502 return cxstring::createRef("NamespaceRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003503 case CXCursor_MemberRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003504 return cxstring::createRef("MemberRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003505 case CXCursor_LabelRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003506 return cxstring::createRef("LabelRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003507 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003508 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003509 case CXCursor_VariableRef:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003510 return cxstring::createRef("VariableRef");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003511 case CXCursor_IntegerLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003512 return cxstring::createRef("IntegerLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003513 case CXCursor_FloatingLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003514 return cxstring::createRef("FloatingLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003515 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003516 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003517 case CXCursor_StringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003518 return cxstring::createRef("StringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003519 case CXCursor_CharacterLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003520 return cxstring::createRef("CharacterLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003521 case CXCursor_ParenExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003522 return cxstring::createRef("ParenExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003523 case CXCursor_UnaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003524 return cxstring::createRef("UnaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003525 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003526 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003527 case CXCursor_BinaryOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003528 return cxstring::createRef("BinaryOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003529 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003530 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003531 case CXCursor_ConditionalOperator:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003532 return cxstring::createRef("ConditionalOperator");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003533 case CXCursor_CStyleCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003534 return cxstring::createRef("CStyleCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003535 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003536 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003537 case CXCursor_InitListExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003538 return cxstring::createRef("InitListExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003539 case CXCursor_AddrLabelExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003540 return cxstring::createRef("AddrLabelExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003541 case CXCursor_StmtExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003542 return cxstring::createRef("StmtExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003543 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003544 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003545 case CXCursor_GNUNullExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003546 return cxstring::createRef("GNUNullExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003547 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003548 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003549 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003550 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003551 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003552 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003553 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003554 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003555 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003556 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003557 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003558 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003559 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003560 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003561 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003562 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003563 case CXCursor_CXXThisExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003564 return cxstring::createRef("CXXThisExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003565 case CXCursor_CXXThrowExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003566 return cxstring::createRef("CXXThrowExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003567 case CXCursor_CXXNewExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003568 return cxstring::createRef("CXXNewExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003569 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003570 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003571 case CXCursor_UnaryExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003572 return cxstring::createRef("UnaryExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003573 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003574 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003575 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003576 return cxstring::createRef("ObjCBoolLiteralExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003577 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003578 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003579 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003580 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003581 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003582 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003583 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003584 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003585 case CXCursor_BlockExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003586 return cxstring::createRef("BlockExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003587 case CXCursor_PackExpansionExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003588 return cxstring::createRef("PackExpansionExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003589 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003590 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003591 case CXCursor_LambdaExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003592 return cxstring::createRef("LambdaExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003593 case CXCursor_UnexposedExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003594 return cxstring::createRef("UnexposedExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003595 case CXCursor_DeclRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003596 return cxstring::createRef("DeclRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003597 case CXCursor_MemberRefExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003598 return cxstring::createRef("MemberRefExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003599 case CXCursor_CallExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003600 return cxstring::createRef("CallExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003601 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003602 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003603 case CXCursor_UnexposedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003604 return cxstring::createRef("UnexposedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003605 case CXCursor_DeclStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003606 return cxstring::createRef("DeclStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003607 case CXCursor_LabelStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003608 return cxstring::createRef("LabelStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003609 case CXCursor_CompoundStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003610 return cxstring::createRef("CompoundStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003611 case CXCursor_CaseStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003612 return cxstring::createRef("CaseStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003613 case CXCursor_DefaultStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003614 return cxstring::createRef("DefaultStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003615 case CXCursor_IfStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003616 return cxstring::createRef("IfStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003617 case CXCursor_SwitchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003618 return cxstring::createRef("SwitchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003619 case CXCursor_WhileStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003620 return cxstring::createRef("WhileStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003621 case CXCursor_DoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003622 return cxstring::createRef("DoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003623 case CXCursor_ForStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003624 return cxstring::createRef("ForStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003625 case CXCursor_GotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003626 return cxstring::createRef("GotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003627 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003628 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003629 case CXCursor_ContinueStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003630 return cxstring::createRef("ContinueStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003631 case CXCursor_BreakStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003632 return cxstring::createRef("BreakStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003633 case CXCursor_ReturnStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003634 return cxstring::createRef("ReturnStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003635 case CXCursor_GCCAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003636 return cxstring::createRef("GCCAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003637 case CXCursor_MSAsmStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003638 return cxstring::createRef("MSAsmStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003639 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003640 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003641 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003642 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003643 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003644 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003645 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003646 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003647 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003648 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003649 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003650 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003651 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003652 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003653 case CXCursor_CXXCatchStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003654 return cxstring::createRef("CXXCatchStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003655 case CXCursor_CXXTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003656 return cxstring::createRef("CXXTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003657 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003658 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003659 case CXCursor_SEHTryStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003660 return cxstring::createRef("SEHTryStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003661 case CXCursor_SEHExceptStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003662 return cxstring::createRef("SEHExceptStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003663 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003664 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003665 case CXCursor_NullStmt:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003666 return cxstring::createRef("NullStmt");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003667 case CXCursor_InvalidFile:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003668 return cxstring::createRef("InvalidFile");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003669 case CXCursor_InvalidCode:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003670 return cxstring::createRef("InvalidCode");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003671 case CXCursor_NoDeclFound:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003672 return cxstring::createRef("NoDeclFound");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003673 case CXCursor_NotImplemented:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003674 return cxstring::createRef("NotImplemented");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003675 case CXCursor_TranslationUnit:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003676 return cxstring::createRef("TranslationUnit");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003677 case CXCursor_UnexposedAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003678 return cxstring::createRef("UnexposedAttr");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003679 case CXCursor_IBActionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003680 return cxstring::createRef("attribute(ibaction)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003681 case CXCursor_IBOutletAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003682 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003683 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003684 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003685 case CXCursor_CXXFinalAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003686 return cxstring::createRef("attribute(final)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003687 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003688 return cxstring::createRef("attribute(override)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003689 case CXCursor_AnnotateAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003690 return cxstring::createRef("attribute(annotate)");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003691 case CXCursor_AsmLabelAttr:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003692 return cxstring::createRef("asm label");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003693 case CXCursor_PreprocessingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003694 return cxstring::createRef("preprocessing directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003695 case CXCursor_MacroDefinition:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003696 return cxstring::createRef("macro definition");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003697 case CXCursor_MacroExpansion:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003698 return cxstring::createRef("macro expansion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003699 case CXCursor_InclusionDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003700 return cxstring::createRef("inclusion directive");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003701 case CXCursor_Namespace:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003702 return cxstring::createRef("Namespace");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003703 case CXCursor_LinkageSpec:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003704 return cxstring::createRef("LinkageSpec");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003705 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003706 return cxstring::createRef("C++ base class specifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003707 case CXCursor_Constructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003708 return cxstring::createRef("CXXConstructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003709 case CXCursor_Destructor:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003710 return cxstring::createRef("CXXDestructor");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003711 case CXCursor_ConversionFunction:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003712 return cxstring::createRef("CXXConversion");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003713 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003714 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003715 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003716 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003717 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003718 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003719 case CXCursor_FunctionTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003720 return cxstring::createRef("FunctionTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003721 case CXCursor_ClassTemplate:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003722 return cxstring::createRef("ClassTemplate");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003723 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003724 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003725 case CXCursor_NamespaceAlias:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003726 return cxstring::createRef("NamespaceAlias");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003727 case CXCursor_UsingDirective:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003728 return cxstring::createRef("UsingDirective");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003729 case CXCursor_UsingDeclaration:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003730 return cxstring::createRef("UsingDeclaration");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003731 case CXCursor_TypeAliasDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003732 return cxstring::createRef("TypeAliasDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003733 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003734 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003735 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003736 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003737 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003738 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003739 case CXCursor_ModuleImportDecl:
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00003740 return cxstring::createRef("ModuleImport");
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003741 }
3742
3743 llvm_unreachable("Unhandled CXCursorKind");
3744}
3745
3746struct GetCursorData {
3747 SourceLocation TokenBeginLoc;
3748 bool PointsAtMacroArgExpansion;
3749 bool VisitedObjCPropertyImplDecl;
3750 SourceLocation VisitedDeclaratorDeclStartLoc;
3751 CXCursor &BestCursor;
3752
3753 GetCursorData(SourceManager &SM,
3754 SourceLocation tokenBegin, CXCursor &outputCursor)
3755 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3756 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3757 VisitedObjCPropertyImplDecl = false;
3758 }
3759};
3760
3761static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3762 CXCursor parent,
3763 CXClientData client_data) {
3764 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3765 CXCursor *BestCursor = &Data->BestCursor;
3766
3767 // If we point inside a macro argument we should provide info of what the
3768 // token is so use the actual cursor, don't replace it with a macro expansion
3769 // cursor.
3770 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3771 return CXChildVisit_Recurse;
3772
3773 if (clang_isDeclaration(cursor.kind)) {
3774 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003775 if (const ObjCMethodDecl *MD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003776 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3777 if (MD->isImplicit())
3778 return CXChildVisit_Break;
3779
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003780 } else if (const ObjCInterfaceDecl *ID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003781 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3782 // Check that when we have multiple @class references in the same line,
3783 // that later ones do not override the previous ones.
3784 // If we have:
3785 // @class Foo, Bar;
3786 // source ranges for both start at '@', so 'Bar' will end up overriding
3787 // 'Foo' even though the cursor location was at 'Foo'.
3788 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3789 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003790 if (const ObjCInterfaceDecl *PrevID
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003791 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3792 if (PrevID != ID &&
3793 !PrevID->isThisDeclarationADefinition() &&
3794 !ID->isThisDeclarationADefinition())
3795 return CXChildVisit_Break;
3796 }
3797
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003798 } else if (const DeclaratorDecl *DD
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003799 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3800 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3801 // Check that when we have multiple declarators in the same line,
3802 // that later ones do not override the previous ones.
3803 // If we have:
3804 // int Foo, Bar;
3805 // source ranges for both start at 'int', so 'Bar' will end up overriding
3806 // 'Foo' even though the cursor location was at 'Foo'.
3807 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3808 return CXChildVisit_Break;
3809 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3810
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003811 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003812 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3813 (void)PropImp;
3814 // Check that when we have multiple @synthesize in the same line,
3815 // that later ones do not override the previous ones.
3816 // If we have:
3817 // @synthesize Foo, Bar;
3818 // source ranges for both start at '@', so 'Bar' will end up overriding
3819 // 'Foo' even though the cursor location was at 'Foo'.
3820 if (Data->VisitedObjCPropertyImplDecl)
3821 return CXChildVisit_Break;
3822 Data->VisitedObjCPropertyImplDecl = true;
3823 }
3824 }
3825
3826 if (clang_isExpression(cursor.kind) &&
3827 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00003828 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003829 // Avoid having the cursor of an expression replace the declaration cursor
3830 // when the expression source range overlaps the declaration range.
3831 // This can happen for C++ constructor expressions whose range generally
3832 // include the variable declaration, e.g.:
3833 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3834 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
3835 D->getLocation() == Data->TokenBeginLoc)
3836 return CXChildVisit_Break;
3837 }
3838 }
3839
3840 // If our current best cursor is the construction of a temporary object,
3841 // don't replace that cursor with a type reference, because we want
3842 // clang_getCursor() to point at the constructor.
3843 if (clang_isExpression(BestCursor->kind) &&
3844 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
3845 cursor.kind == CXCursor_TypeRef) {
3846 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
3847 // as having the actual point on the type reference.
3848 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
3849 return CXChildVisit_Recurse;
3850 }
3851
3852 *BestCursor = cursor;
3853 return CXChildVisit_Recurse;
3854}
3855
3856CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
3857 if (!TU)
3858 return clang_getNullCursor();
3859
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00003860 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003861 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3862
3863 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
3864 CXCursor Result = cxcursor::getCursor(TU, SLoc);
3865
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003866 LOG_FUNC_SECTION {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003867 CXFile SearchFile;
3868 unsigned SearchLine, SearchColumn;
3869 CXFile ResultFile;
3870 unsigned ResultLine, ResultColumn;
3871 CXString SearchFileName, ResultFileName, KindSpelling, USR;
3872 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
3873 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
3874
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003875 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
3876 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003877 &ResultColumn, 0);
3878 SearchFileName = clang_getFileName(SearchFile);
3879 ResultFileName = clang_getFileName(ResultFile);
3880 KindSpelling = clang_getCursorKindSpelling(Result.kind);
3881 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003882 *Log << llvm::format("(%s:%d:%d) = %s",
3883 clang_getCString(SearchFileName), SearchLine, SearchColumn,
3884 clang_getCString(KindSpelling))
3885 << llvm::format("(%s:%d:%d):%s%s",
3886 clang_getCString(ResultFileName), ResultLine, ResultColumn,
3887 clang_getCString(USR), IsDef);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003888 clang_disposeString(SearchFileName);
3889 clang_disposeString(ResultFileName);
3890 clang_disposeString(KindSpelling);
3891 clang_disposeString(USR);
3892
3893 CXCursor Definition = clang_getCursorDefinition(Result);
3894 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
3895 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
3896 CXString DefinitionKindSpelling
3897 = clang_getCursorKindSpelling(Definition.kind);
3898 CXFile DefinitionFile;
3899 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003900 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003901 &DefinitionLine, &DefinitionColumn, 0);
3902 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00003903 *Log << llvm::format(" -> %s(%s:%d:%d)",
3904 clang_getCString(DefinitionKindSpelling),
3905 clang_getCString(DefinitionFileName),
3906 DefinitionLine, DefinitionColumn);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003907 clang_disposeString(DefinitionFileName);
3908 clang_disposeString(DefinitionKindSpelling);
3909 }
3910 }
3911
3912 return Result;
3913}
3914
3915CXCursor clang_getNullCursor(void) {
3916 return MakeCXCursorInvalid(CXCursor_InvalidFile);
3917}
3918
3919unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisd1d9df62013-01-08 18:23:28 +00003920 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
3921 // can't set consistently. For example, when visiting a DeclStmt we will set
3922 // it but we don't set it on the result of clang_getCursorDefinition for
3923 // a reference of the same declaration.
3924 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
3925 // when visiting a DeclStmt currently, the AST should be enhanced to be able
3926 // to provide that kind of info.
3927 if (clang_isDeclaration(X.kind))
3928 X.data[1] = 0;
3929 if (clang_isDeclaration(Y.kind))
3930 Y.data[1] = 0;
3931
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003932 return X == Y;
3933}
3934
3935unsigned clang_hashCursor(CXCursor C) {
3936 unsigned Index = 0;
3937 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
3938 Index = 1;
3939
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003940 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003941 std::make_pair(C.kind, C.data[Index]));
3942}
3943
3944unsigned clang_isInvalid(enum CXCursorKind K) {
3945 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
3946}
3947
3948unsigned clang_isDeclaration(enum CXCursorKind K) {
3949 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
3950 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
3951}
3952
3953unsigned clang_isReference(enum CXCursorKind K) {
3954 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
3955}
3956
3957unsigned clang_isExpression(enum CXCursorKind K) {
3958 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
3959}
3960
3961unsigned clang_isStatement(enum CXCursorKind K) {
3962 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
3963}
3964
3965unsigned clang_isAttribute(enum CXCursorKind K) {
3966 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
3967}
3968
3969unsigned clang_isTranslationUnit(enum CXCursorKind K) {
3970 return K == CXCursor_TranslationUnit;
3971}
3972
3973unsigned clang_isPreprocessing(enum CXCursorKind K) {
3974 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
3975}
3976
3977unsigned clang_isUnexposed(enum CXCursorKind K) {
3978 switch (K) {
3979 case CXCursor_UnexposedDecl:
3980 case CXCursor_UnexposedExpr:
3981 case CXCursor_UnexposedStmt:
3982 case CXCursor_UnexposedAttr:
3983 return true;
3984 default:
3985 return false;
3986 }
3987}
3988
3989CXCursorKind clang_getCursorKind(CXCursor C) {
3990 return C.kind;
3991}
3992
3993CXSourceLocation clang_getCursorLocation(CXCursor C) {
3994 if (clang_isReference(C.kind)) {
3995 switch (C.kind) {
3996 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00003997 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00003998 = getCursorObjCSuperClassRef(C);
3999 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4000 }
4001
4002 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004003 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004004 = getCursorObjCProtocolRef(C);
4005 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4006 }
4007
4008 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004009 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004010 = getCursorObjCClassRef(C);
4011 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4012 }
4013
4014 case CXCursor_TypeRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004015 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004016 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4017 }
4018
4019 case CXCursor_TemplateRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004020 std::pair<const TemplateDecl *, SourceLocation> P =
4021 getCursorTemplateRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004022 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4023 }
4024
4025 case CXCursor_NamespaceRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004026 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004027 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4028 }
4029
4030 case CXCursor_MemberRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004031 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004032 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4033 }
4034
4035 case CXCursor_VariableRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004036 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004037 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4038 }
4039
4040 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004041 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004042 if (!BaseSpec)
4043 return clang_getNullLocation();
4044
4045 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4046 return cxloc::translateSourceLocation(getCursorContext(C),
4047 TSInfo->getTypeLoc().getBeginLoc());
4048
4049 return cxloc::translateSourceLocation(getCursorContext(C),
4050 BaseSpec->getLocStart());
4051 }
4052
4053 case CXCursor_LabelRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004054 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004055 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4056 }
4057
4058 case CXCursor_OverloadedDeclRef:
4059 return cxloc::translateSourceLocation(getCursorContext(C),
4060 getCursorOverloadedDeclRef(C).second);
4061
4062 default:
4063 // FIXME: Need a way to enumerate all non-reference cases.
4064 llvm_unreachable("Missed a reference kind");
4065 }
4066 }
4067
4068 if (clang_isExpression(C.kind))
4069 return cxloc::translateSourceLocation(getCursorContext(C),
4070 getLocationFromExpr(getCursorExpr(C)));
4071
4072 if (clang_isStatement(C.kind))
4073 return cxloc::translateSourceLocation(getCursorContext(C),
4074 getCursorStmt(C)->getLocStart());
4075
4076 if (C.kind == CXCursor_PreprocessingDirective) {
4077 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4078 return cxloc::translateSourceLocation(getCursorContext(C), L);
4079 }
4080
4081 if (C.kind == CXCursor_MacroExpansion) {
4082 SourceLocation L
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004083 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004084 return cxloc::translateSourceLocation(getCursorContext(C), L);
4085 }
4086
4087 if (C.kind == CXCursor_MacroDefinition) {
4088 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4089 return cxloc::translateSourceLocation(getCursorContext(C), L);
4090 }
4091
4092 if (C.kind == CXCursor_InclusionDirective) {
4093 SourceLocation L
4094 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4095 return cxloc::translateSourceLocation(getCursorContext(C), L);
4096 }
4097
4098 if (!clang_isDeclaration(C.kind))
4099 return clang_getNullLocation();
4100
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004101 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004102 if (!D)
4103 return clang_getNullLocation();
4104
4105 SourceLocation Loc = D->getLocation();
4106 // FIXME: Multiple variables declared in a single declaration
4107 // currently lack the information needed to correctly determine their
4108 // ranges when accounting for the type-specifier. We use context
4109 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4110 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004111 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004112 if (!cxcursor::isFirstInDeclGroup(C))
4113 Loc = VD->getLocation();
4114 }
4115
4116 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004117 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004118 Loc = MD->getSelectorStartLoc();
4119
4120 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4121}
4122
4123} // end extern "C"
4124
4125CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4126 assert(TU);
4127
4128 // Guard against an invalid SourceLocation, or we may assert in one
4129 // of the following calls.
4130 if (SLoc.isInvalid())
4131 return clang_getNullCursor();
4132
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004133 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004134
4135 // Translate the given source location to make it point at the beginning of
4136 // the token under the cursor.
4137 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4138 CXXUnit->getASTContext().getLangOpts());
4139
4140 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4141 if (SLoc.isValid()) {
4142 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4143 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4144 /*VisitPreprocessorLast=*/true,
4145 /*VisitIncludedEntities=*/false,
4146 SourceLocation(SLoc));
4147 CursorVis.visitFileRegion();
4148 }
4149
4150 return Result;
4151}
4152
4153static SourceRange getRawCursorExtent(CXCursor C) {
4154 if (clang_isReference(C.kind)) {
4155 switch (C.kind) {
4156 case CXCursor_ObjCSuperClassRef:
4157 return getCursorObjCSuperClassRef(C).second;
4158
4159 case CXCursor_ObjCProtocolRef:
4160 return getCursorObjCProtocolRef(C).second;
4161
4162 case CXCursor_ObjCClassRef:
4163 return getCursorObjCClassRef(C).second;
4164
4165 case CXCursor_TypeRef:
4166 return getCursorTypeRef(C).second;
4167
4168 case CXCursor_TemplateRef:
4169 return getCursorTemplateRef(C).second;
4170
4171 case CXCursor_NamespaceRef:
4172 return getCursorNamespaceRef(C).second;
4173
4174 case CXCursor_MemberRef:
4175 return getCursorMemberRef(C).second;
4176
4177 case CXCursor_CXXBaseSpecifier:
4178 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4179
4180 case CXCursor_LabelRef:
4181 return getCursorLabelRef(C).second;
4182
4183 case CXCursor_OverloadedDeclRef:
4184 return getCursorOverloadedDeclRef(C).second;
4185
4186 case CXCursor_VariableRef:
4187 return getCursorVariableRef(C).second;
4188
4189 default:
4190 // FIXME: Need a way to enumerate all non-reference cases.
4191 llvm_unreachable("Missed a reference kind");
4192 }
4193 }
4194
4195 if (clang_isExpression(C.kind))
4196 return getCursorExpr(C)->getSourceRange();
4197
4198 if (clang_isStatement(C.kind))
4199 return getCursorStmt(C)->getSourceRange();
4200
4201 if (clang_isAttribute(C.kind))
4202 return getCursorAttr(C)->getRange();
4203
4204 if (C.kind == CXCursor_PreprocessingDirective)
4205 return cxcursor::getCursorPreprocessingDirective(C);
4206
4207 if (C.kind == CXCursor_MacroExpansion) {
4208 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00004209 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004210 return TU->mapRangeFromPreamble(Range);
4211 }
4212
4213 if (C.kind == CXCursor_MacroDefinition) {
4214 ASTUnit *TU = getCursorASTUnit(C);
4215 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4216 return TU->mapRangeFromPreamble(Range);
4217 }
4218
4219 if (C.kind == CXCursor_InclusionDirective) {
4220 ASTUnit *TU = getCursorASTUnit(C);
4221 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4222 return TU->mapRangeFromPreamble(Range);
4223 }
4224
4225 if (C.kind == CXCursor_TranslationUnit) {
4226 ASTUnit *TU = getCursorASTUnit(C);
4227 FileID MainID = TU->getSourceManager().getMainFileID();
4228 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4229 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4230 return SourceRange(Start, End);
4231 }
4232
4233 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004234 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004235 if (!D)
4236 return SourceRange();
4237
4238 SourceRange R = D->getSourceRange();
4239 // FIXME: Multiple variables declared in a single declaration
4240 // currently lack the information needed to correctly determine their
4241 // ranges when accounting for the type-specifier. We use context
4242 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4243 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004244 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004245 if (!cxcursor::isFirstInDeclGroup(C))
4246 R.setBegin(VD->getLocation());
4247 }
4248 return R;
4249 }
4250 return SourceRange();
4251}
4252
4253/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4254/// the decl-specifier-seq for declarations.
4255static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4256 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004257 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004258 if (!D)
4259 return SourceRange();
4260
4261 SourceRange R = D->getSourceRange();
4262
4263 // Adjust the start of the location for declarations preceded by
4264 // declaration specifiers.
4265 SourceLocation StartLoc;
4266 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4267 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4268 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004269 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004270 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4271 StartLoc = TI->getTypeLoc().getLocStart();
4272 }
4273
4274 if (StartLoc.isValid() && R.getBegin().isValid() &&
4275 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4276 R.setBegin(StartLoc);
4277
4278 // FIXME: Multiple variables declared in a single declaration
4279 // currently lack the information needed to correctly determine their
4280 // ranges when accounting for the type-specifier. We use context
4281 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4282 // and if so, whether it is the first decl.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004283 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004284 if (!cxcursor::isFirstInDeclGroup(C))
4285 R.setBegin(VD->getLocation());
4286 }
4287
4288 return R;
4289 }
4290
4291 return getRawCursorExtent(C);
4292}
4293
4294extern "C" {
4295
4296CXSourceRange clang_getCursorExtent(CXCursor C) {
4297 SourceRange R = getRawCursorExtent(C);
4298 if (R.isInvalid())
4299 return clang_getNullRange();
4300
4301 return cxloc::translateSourceRange(getCursorContext(C), R);
4302}
4303
4304CXCursor clang_getCursorReferenced(CXCursor C) {
4305 if (clang_isInvalid(C.kind))
4306 return clang_getNullCursor();
4307
4308 CXTranslationUnit tu = getCursorTU(C);
4309 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004310 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004311 if (!D)
4312 return clang_getNullCursor();
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004313 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004314 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004315 if (const ObjCPropertyImplDecl *PropImpl =
4316 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004317 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4318 return MakeCXCursor(Property, tu);
4319
4320 return C;
4321 }
4322
4323 if (clang_isExpression(C.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004324 const Expr *E = getCursorExpr(C);
4325 const Decl *D = getDeclFromExpr(E);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004326 if (D) {
4327 CXCursor declCursor = MakeCXCursor(D, tu);
4328 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4329 declCursor);
4330 return declCursor;
4331 }
4332
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004333 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004334 return MakeCursorOverloadedDeclRef(Ovl, tu);
4335
4336 return clang_getNullCursor();
4337 }
4338
4339 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004340 const Stmt *S = getCursorStmt(C);
4341 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004342 if (LabelDecl *label = Goto->getLabel())
4343 if (LabelStmt *labelS = label->getStmt())
4344 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4345
4346 return clang_getNullCursor();
4347 }
4348
4349 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004350 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004351 return MakeMacroDefinitionCursor(Def, tu);
4352 }
4353
4354 if (!clang_isReference(C.kind))
4355 return clang_getNullCursor();
4356
4357 switch (C.kind) {
4358 case CXCursor_ObjCSuperClassRef:
4359 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4360
4361 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004362 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4363 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004364 return MakeCXCursor(Def, tu);
4365
4366 return MakeCXCursor(Prot, tu);
4367 }
4368
4369 case CXCursor_ObjCClassRef: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004370 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4371 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004372 return MakeCXCursor(Def, tu);
4373
4374 return MakeCXCursor(Class, tu);
4375 }
4376
4377 case CXCursor_TypeRef:
4378 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4379
4380 case CXCursor_TemplateRef:
4381 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4382
4383 case CXCursor_NamespaceRef:
4384 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4385
4386 case CXCursor_MemberRef:
4387 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4388
4389 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenko67812b22013-01-11 21:01:49 +00004390 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004391 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4392 tu ));
4393 }
4394
4395 case CXCursor_LabelRef:
4396 // FIXME: We end up faking the "parent" declaration here because we
4397 // don't want to make CXCursor larger.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004398 return MakeCXCursor(getCursorLabelRef(C).first,
4399 cxtu::getASTUnit(tu)->getASTContext()
4400 .getTranslationUnitDecl(),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004401 tu);
4402
4403 case CXCursor_OverloadedDeclRef:
4404 return C;
4405
4406 case CXCursor_VariableRef:
4407 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4408
4409 default:
4410 // We would prefer to enumerate all non-reference cursor kinds here.
4411 llvm_unreachable("Unhandled reference cursor kind");
4412 }
4413}
4414
4415CXCursor clang_getCursorDefinition(CXCursor C) {
4416 if (clang_isInvalid(C.kind))
4417 return clang_getNullCursor();
4418
4419 CXTranslationUnit TU = getCursorTU(C);
4420
4421 bool WasReference = false;
4422 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4423 C = clang_getCursorReferenced(C);
4424 WasReference = true;
4425 }
4426
4427 if (C.kind == CXCursor_MacroExpansion)
4428 return clang_getCursorReferenced(C);
4429
4430 if (!clang_isDeclaration(C.kind))
4431 return clang_getNullCursor();
4432
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004433 const Decl *D = getCursorDecl(C);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004434 if (!D)
4435 return clang_getNullCursor();
4436
4437 switch (D->getKind()) {
4438 // Declaration kinds that don't really separate the notions of
4439 // declaration and definition.
4440 case Decl::Namespace:
4441 case Decl::Typedef:
4442 case Decl::TypeAlias:
4443 case Decl::TypeAliasTemplate:
4444 case Decl::TemplateTypeParm:
4445 case Decl::EnumConstant:
4446 case Decl::Field:
4447 case Decl::IndirectField:
4448 case Decl::ObjCIvar:
4449 case Decl::ObjCAtDefsField:
4450 case Decl::ImplicitParam:
4451 case Decl::ParmVar:
4452 case Decl::NonTypeTemplateParm:
4453 case Decl::TemplateTemplateParm:
4454 case Decl::ObjCCategoryImpl:
4455 case Decl::ObjCImplementation:
4456 case Decl::AccessSpec:
4457 case Decl::LinkageSpec:
4458 case Decl::ObjCPropertyImpl:
4459 case Decl::FileScopeAsm:
4460 case Decl::StaticAssert:
4461 case Decl::Block:
4462 case Decl::Label: // FIXME: Is this right??
4463 case Decl::ClassScopeFunctionSpecialization:
4464 case Decl::Import:
Alexey Bataevc6400582013-03-22 06:34:35 +00004465 case Decl::OMPThreadPrivate:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004466 return C;
4467
4468 // Declaration kinds that don't make any sense here, but are
4469 // nonetheless harmless.
David Blaikief23546a2013-02-22 17:44:58 +00004470 case Decl::Empty:
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004471 case Decl::TranslationUnit:
4472 break;
4473
4474 // Declaration kinds for which the definition is not resolvable.
4475 case Decl::UnresolvedUsingTypename:
4476 case Decl::UnresolvedUsingValue:
4477 break;
4478
4479 case Decl::UsingDirective:
4480 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4481 TU);
4482
4483 case Decl::NamespaceAlias:
4484 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4485
4486 case Decl::Enum:
4487 case Decl::Record:
4488 case Decl::CXXRecord:
4489 case Decl::ClassTemplateSpecialization:
4490 case Decl::ClassTemplatePartialSpecialization:
4491 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4492 return MakeCXCursor(Def, TU);
4493 return clang_getNullCursor();
4494
4495 case Decl::Function:
4496 case Decl::CXXMethod:
4497 case Decl::CXXConstructor:
4498 case Decl::CXXDestructor:
4499 case Decl::CXXConversion: {
4500 const FunctionDecl *Def = 0;
4501 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko05756dc2013-01-14 00:46:27 +00004502 return MakeCXCursor(Def, TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004503 return clang_getNullCursor();
4504 }
4505
4506 case Decl::Var: {
4507 // Ask the variable if it has a definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004508 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004509 return MakeCXCursor(Def, TU);
4510 return clang_getNullCursor();
4511 }
4512
4513 case Decl::FunctionTemplate: {
4514 const FunctionDecl *Def = 0;
4515 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4516 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4517 return clang_getNullCursor();
4518 }
4519
4520 case Decl::ClassTemplate: {
4521 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4522 ->getDefinition())
4523 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4524 TU);
4525 return clang_getNullCursor();
4526 }
4527
4528 case Decl::Using:
4529 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4530 D->getLocation(), TU);
4531
4532 case Decl::UsingShadow:
4533 return clang_getCursorDefinition(
4534 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4535 TU));
4536
4537 case Decl::ObjCMethod: {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004538 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004539 if (Method->isThisDeclarationADefinition())
4540 return C;
4541
4542 // Dig out the method definition in the associated
4543 // @implementation, if we have it.
4544 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004545 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004546 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4547 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4548 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4549 Method->isInstanceMethod()))
4550 if (Def->isThisDeclarationADefinition())
4551 return MakeCXCursor(Def, TU);
4552
4553 return clang_getNullCursor();
4554 }
4555
4556 case Decl::ObjCCategory:
4557 if (ObjCCategoryImplDecl *Impl
4558 = cast<ObjCCategoryDecl>(D)->getImplementation())
4559 return MakeCXCursor(Impl, TU);
4560 return clang_getNullCursor();
4561
4562 case Decl::ObjCProtocol:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004563 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004564 return MakeCXCursor(Def, TU);
4565 return clang_getNullCursor();
4566
4567 case Decl::ObjCInterface: {
4568 // There are two notions of a "definition" for an Objective-C
4569 // class: the interface and its implementation. When we resolved a
4570 // reference to an Objective-C class, produce the @interface as
4571 // the definition; when we were provided with the interface,
4572 // produce the @implementation as the definition.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004573 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004574 if (WasReference) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004575 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004576 return MakeCXCursor(Def, TU);
4577 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4578 return MakeCXCursor(Impl, TU);
4579 return clang_getNullCursor();
4580 }
4581
4582 case Decl::ObjCProperty:
4583 // FIXME: We don't really know where to find the
4584 // ObjCPropertyImplDecls that implement this property.
4585 return clang_getNullCursor();
4586
4587 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004588 if (const ObjCInterfaceDecl *Class
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004589 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004590 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004591 return MakeCXCursor(Def, TU);
4592
4593 return clang_getNullCursor();
4594
4595 case Decl::Friend:
4596 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4597 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4598 return clang_getNullCursor();
4599
4600 case Decl::FriendTemplate:
4601 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4602 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4603 return clang_getNullCursor();
4604 }
4605
4606 return clang_getNullCursor();
4607}
4608
4609unsigned clang_isCursorDefinition(CXCursor C) {
4610 if (!clang_isDeclaration(C.kind))
4611 return 0;
4612
4613 return clang_getCursorDefinition(C) == C;
4614}
4615
4616CXCursor clang_getCanonicalCursor(CXCursor C) {
4617 if (!clang_isDeclaration(C.kind))
4618 return C;
4619
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004620 if (const Decl *D = getCursorDecl(C)) {
4621 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004622 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4623 return MakeCXCursor(CatD, getCursorTU(C));
4624
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004625 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4626 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004627 return MakeCXCursor(IFD, getCursorTU(C));
4628
4629 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4630 }
4631
4632 return C;
4633}
4634
4635int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4636 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4637}
4638
4639unsigned clang_getNumOverloadedDecls(CXCursor C) {
4640 if (C.kind != CXCursor_OverloadedDeclRef)
4641 return 0;
4642
4643 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004644 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004645 return E->getNumDecls();
4646
4647 if (OverloadedTemplateStorage *S
4648 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4649 return S->size();
4650
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004651 const Decl *D = Storage.get<const Decl *>();
4652 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004653 return Using->shadow_size();
4654
4655 return 0;
4656}
4657
4658CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4659 if (cursor.kind != CXCursor_OverloadedDeclRef)
4660 return clang_getNullCursor();
4661
4662 if (index >= clang_getNumOverloadedDecls(cursor))
4663 return clang_getNullCursor();
4664
4665 CXTranslationUnit TU = getCursorTU(cursor);
4666 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004667 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004668 return MakeCXCursor(E->decls_begin()[index], TU);
4669
4670 if (OverloadedTemplateStorage *S
4671 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4672 return MakeCXCursor(S->begin()[index], TU);
4673
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004674 const Decl *D = Storage.get<const Decl *>();
4675 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004676 // FIXME: This is, unfortunately, linear time.
4677 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4678 std::advance(Pos, index);
4679 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4680 }
4681
4682 return clang_getNullCursor();
4683}
4684
4685void clang_getDefinitionSpellingAndExtent(CXCursor C,
4686 const char **startBuf,
4687 const char **endBuf,
4688 unsigned *startLine,
4689 unsigned *startColumn,
4690 unsigned *endLine,
4691 unsigned *endColumn) {
4692 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00004693 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004694 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4695
4696 SourceManager &SM = FD->getASTContext().getSourceManager();
4697 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4698 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4699 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4700 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4701 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4702 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4703}
4704
4705
4706CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4707 unsigned PieceIndex) {
4708 RefNamePieces Pieces;
4709
4710 switch (C.kind) {
4711 case CXCursor_MemberRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004712 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004713 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4714 E->getQualifierLoc().getSourceRange());
4715 break;
4716
4717 case CXCursor_DeclRefExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004718 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004719 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4720 E->getQualifierLoc().getSourceRange(),
4721 E->getOptionalExplicitTemplateArgs());
4722 break;
4723
4724 case CXCursor_CallExpr:
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004725 if (const CXXOperatorCallExpr *OCE =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004726 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004727 const Expr *Callee = OCE->getCallee();
4728 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004729 Callee = ICE->getSubExpr();
4730
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00004731 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004732 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4733 DRE->getQualifierLoc().getSourceRange());
4734 }
4735 break;
4736
4737 default:
4738 break;
4739 }
4740
4741 if (Pieces.empty()) {
4742 if (PieceIndex == 0)
4743 return clang_getCursorExtent(C);
4744 } else if (PieceIndex < Pieces.size()) {
4745 SourceRange R = Pieces[PieceIndex];
4746 if (R.isValid())
4747 return cxloc::translateSourceRange(getCursorContext(C), R);
4748 }
4749
4750 return clang_getNullRange();
4751}
4752
4753void clang_enableStackTraces(void) {
4754 llvm::sys::PrintStackTraceOnErrorSignal();
4755}
4756
4757void clang_executeOnThread(void (*fn)(void*), void *user_data,
4758 unsigned stack_size) {
4759 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4760}
4761
4762} // end: extern "C"
4763
4764//===----------------------------------------------------------------------===//
4765// Token-based Operations.
4766//===----------------------------------------------------------------------===//
4767
4768/* CXToken layout:
4769 * int_data[0]: a CXTokenKind
4770 * int_data[1]: starting token location
4771 * int_data[2]: token length
4772 * int_data[3]: reserved
4773 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4774 * otherwise unused.
4775 */
4776extern "C" {
4777
4778CXTokenKind clang_getTokenKind(CXToken CXTok) {
4779 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4780}
4781
4782CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4783 switch (clang_getTokenKind(CXTok)) {
4784 case CXToken_Identifier:
4785 case CXToken_Keyword:
4786 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko0c4394c2013-02-02 00:02:12 +00004787 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004788 ->getNameStart());
4789
4790 case CXToken_Literal: {
4791 // We have stashed the starting pointer in the ptr_data field. Use it.
4792 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004793 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004794 }
4795
4796 case CXToken_Punctuation:
4797 case CXToken_Comment:
4798 break;
4799 }
4800
4801 // We have to find the starting buffer pointer the hard way, by
4802 // deconstructing the source location.
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004803 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004804 if (!CXXUnit)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004805 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004806
4807 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4808 std::pair<FileID, unsigned> LocInfo
4809 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4810 bool Invalid = false;
4811 StringRef Buffer
4812 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
4813 if (Invalid)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00004814 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004815
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00004816 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004817}
4818
4819CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004820 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004821 if (!CXXUnit)
4822 return clang_getNullLocation();
4823
4824 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
4825 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4826}
4827
4828CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004829 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004830 if (!CXXUnit)
4831 return clang_getNullRange();
4832
4833 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
4834 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
4835}
4836
4837static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
4838 SmallVectorImpl<CXToken> &CXTokens) {
4839 SourceManager &SourceMgr = CXXUnit->getSourceManager();
4840 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004841 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004842 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00004843 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004844
4845 // Cannot tokenize across files.
4846 if (BeginLocInfo.first != EndLocInfo.first)
4847 return;
4848
4849 // Create a lexer
4850 bool Invalid = false;
4851 StringRef Buffer
4852 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
4853 if (Invalid)
4854 return;
4855
4856 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
4857 CXXUnit->getASTContext().getLangOpts(),
4858 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
4859 Lex.SetCommentRetentionState(true);
4860
4861 // Lex tokens until we hit the end of the range.
4862 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
4863 Token Tok;
4864 bool previousWasAt = false;
4865 do {
4866 // Lex the next token
4867 Lex.LexFromRawLexer(Tok);
4868 if (Tok.is(tok::eof))
4869 break;
4870
4871 // Initialize the CXToken.
4872 CXToken CXTok;
4873
4874 // - Common fields
4875 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
4876 CXTok.int_data[2] = Tok.getLength();
4877 CXTok.int_data[3] = 0;
4878
4879 // - Kind-specific fields
4880 if (Tok.isLiteral()) {
4881 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00004882 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004883 } else if (Tok.is(tok::raw_identifier)) {
4884 // Lookup the identifier to determine whether we have a keyword.
4885 IdentifierInfo *II
4886 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
4887
4888 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
4889 CXTok.int_data[0] = CXToken_Keyword;
4890 }
4891 else {
4892 CXTok.int_data[0] = Tok.is(tok::identifier)
4893 ? CXToken_Identifier
4894 : CXToken_Keyword;
4895 }
4896 CXTok.ptr_data = II;
4897 } else if (Tok.is(tok::comment)) {
4898 CXTok.int_data[0] = CXToken_Comment;
4899 CXTok.ptr_data = 0;
4900 } else {
4901 CXTok.int_data[0] = CXToken_Punctuation;
4902 CXTok.ptr_data = 0;
4903 }
4904 CXTokens.push_back(CXTok);
4905 previousWasAt = Tok.is(tok::at);
4906 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
4907}
4908
4909void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
4910 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00004911 LOG_FUNC_SECTION {
4912 *Log << TU << ' ' << Range;
4913 }
4914
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004915 if (Tokens)
4916 *Tokens = 0;
4917 if (NumTokens)
4918 *NumTokens = 0;
4919
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00004920 if (!TU)
4921 return;
4922
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004923 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004924 if (!CXXUnit || !Tokens || !NumTokens)
4925 return;
4926
4927 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4928
4929 SourceRange R = cxloc::translateCXSourceRange(Range);
4930 if (R.isInvalid())
4931 return;
4932
4933 SmallVector<CXToken, 32> CXTokens;
4934 getTokens(CXXUnit, R, CXTokens);
4935
4936 if (CXTokens.empty())
4937 return;
4938
4939 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
4940 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
4941 *NumTokens = CXTokens.size();
4942}
4943
4944void clang_disposeTokens(CXTranslationUnit TU,
4945 CXToken *Tokens, unsigned NumTokens) {
4946 free(Tokens);
4947}
4948
4949} // end: extern "C"
4950
4951//===----------------------------------------------------------------------===//
4952// Token annotation APIs.
4953//===----------------------------------------------------------------------===//
4954
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004955static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
4956 CXCursor parent,
4957 CXClientData client_data);
4958static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
4959 CXClientData client_data);
4960
4961namespace {
4962class AnnotateTokensWorker {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004963 CXToken *Tokens;
4964 CXCursor *Cursors;
4965 unsigned NumTokens;
4966 unsigned TokIdx;
4967 unsigned PreprocessingTokIdx;
4968 CursorVisitor AnnotateVis;
4969 SourceManager &SrcMgr;
4970 bool HasContextSensitiveKeywords;
4971
4972 struct PostChildrenInfo {
4973 CXCursor Cursor;
4974 SourceRange CursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00004975 unsigned BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004976 unsigned BeforeChildrenTokenIdx;
4977 };
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00004978 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004979
4980 bool MoreTokens() const { return TokIdx < NumTokens; }
4981 unsigned NextToken() const { return TokIdx; }
4982 void AdvanceToken() { ++TokIdx; }
4983 SourceLocation GetTokenLoc(unsigned tokI) {
4984 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
4985 }
4986 bool isFunctionMacroToken(unsigned tokI) const {
4987 return Tokens[tokI].int_data[3] != 0;
4988 }
4989 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
4990 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[3]);
4991 }
4992
4993 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00004994 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00004995 SourceRange);
4996
4997public:
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00004998 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00004999 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005000 : Tokens(tokens), Cursors(cursors),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005001 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005002 AnnotateVis(TU,
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005003 AnnotateTokensVisitor, this,
5004 /*VisitPreprocessorLast=*/true,
5005 /*VisitIncludedEntities=*/false,
5006 RegionOfInterest,
5007 /*VisitDeclsOnly=*/false,
5008 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005009 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005010 HasContextSensitiveKeywords(false) { }
5011
5012 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5013 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5014 bool postVisitChildren(CXCursor cursor);
5015 void AnnotateTokens();
5016
5017 /// \brief Determine whether the annotator saw any cursors that have
5018 /// context-sensitive keywords.
5019 bool hasContextSensitiveKeywords() const {
5020 return HasContextSensitiveKeywords;
5021 }
5022
5023 ~AnnotateTokensWorker() {
5024 assert(PostChildrenInfos.empty());
5025 }
5026};
5027}
5028
5029void AnnotateTokensWorker::AnnotateTokens() {
5030 // Walk the AST within the region of interest, annotating tokens
5031 // along the way.
5032 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005033}
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005034
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005035static inline void updateCursorAnnotation(CXCursor &Cursor,
5036 const CXCursor &updateC) {
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005037 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005038 return;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005039 Cursor = updateC;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005040}
5041
5042/// \brief It annotates and advances tokens with a cursor until the comparison
5043//// between the cursor location and the source range is the same as
5044/// \arg compResult.
5045///
5046/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5047/// Pass RangeOverlap to annotate tokens inside a range.
5048void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5049 RangeComparisonResult compResult,
5050 SourceRange range) {
5051 while (MoreTokens()) {
5052 const unsigned I = NextToken();
5053 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005054 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5055 return;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005056
5057 SourceLocation TokLoc = GetTokenLoc(I);
5058 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005059 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005060 AdvanceToken();
5061 continue;
5062 }
5063 break;
5064 }
5065}
5066
5067/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005068/// \returns true if it advanced beyond all macro tokens, false otherwise.
5069bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005070 CXCursor updateC,
5071 RangeComparisonResult compResult,
5072 SourceRange range) {
5073 assert(MoreTokens());
5074 assert(isFunctionMacroToken(NextToken()) &&
5075 "Should be called only for macro arg tokens");
5076
5077 // This works differently than annotateAndAdvanceTokens; because expanded
5078 // macro arguments can have arbitrary translation-unit source order, we do not
5079 // advance the token index one by one until a token fails the range test.
5080 // We only advance once past all of the macro arg tokens if all of them
5081 // pass the range test. If one of them fails we keep the token index pointing
5082 // at the start of the macro arg tokens so that the failing token will be
5083 // annotated by a subsequent annotation try.
5084
5085 bool atLeastOneCompFail = false;
5086
5087 unsigned I = NextToken();
5088 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5089 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5090 if (TokLoc.isFileID())
5091 continue; // not macro arg token, it's parens or comma.
5092 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5093 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5094 Cursors[I] = updateC;
5095 } else
5096 atLeastOneCompFail = true;
5097 }
5098
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005099 if (atLeastOneCompFail)
5100 return false;
5101
5102 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5103 return true;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005104}
5105
5106enum CXChildVisitResult
5107AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005108 SourceRange cursorRange = getRawCursorExtent(cursor);
5109 if (cursorRange.isInvalid())
5110 return CXChildVisit_Recurse;
5111
5112 if (!HasContextSensitiveKeywords) {
5113 // Objective-C properties can have context-sensitive keywords.
5114 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005115 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005116 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5117 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5118 }
5119 // Objective-C methods can have context-sensitive keywords.
5120 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5121 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005122 if (const ObjCMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005123 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5124 if (Method->getObjCDeclQualifier())
5125 HasContextSensitiveKeywords = true;
5126 else {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005127 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5128 PEnd = Method->param_end();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005129 P != PEnd; ++P) {
5130 if ((*P)->getObjCDeclQualifier()) {
5131 HasContextSensitiveKeywords = true;
5132 break;
5133 }
5134 }
5135 }
5136 }
5137 }
5138 // C++ methods can have context-sensitive keywords.
5139 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005140 if (const CXXMethodDecl *Method
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005141 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5142 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5143 HasContextSensitiveKeywords = true;
5144 }
5145 }
5146 // C++ classes can have context-sensitive keywords.
5147 else if (cursor.kind == CXCursor_StructDecl ||
5148 cursor.kind == CXCursor_ClassDecl ||
5149 cursor.kind == CXCursor_ClassTemplate ||
5150 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005151 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005152 if (D->hasAttr<FinalAttr>())
5153 HasContextSensitiveKeywords = true;
5154 }
5155 }
5156
5157 if (clang_isPreprocessing(cursor.kind)) {
5158 // Items in the preprocessing record are kept separate from items in
5159 // declarations, so we keep a separate token index.
5160 unsigned SavedTokIdx = TokIdx;
5161 TokIdx = PreprocessingTokIdx;
5162
5163 // Skip tokens up until we catch up to the beginning of the preprocessing
5164 // entry.
5165 while (MoreTokens()) {
5166 const unsigned I = NextToken();
5167 SourceLocation TokLoc = GetTokenLoc(I);
5168 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5169 case RangeBefore:
5170 AdvanceToken();
5171 continue;
5172 case RangeAfter:
5173 case RangeOverlap:
5174 break;
5175 }
5176 break;
5177 }
5178
5179 // Look at all of the tokens within this range.
5180 while (MoreTokens()) {
5181 const unsigned I = NextToken();
5182 SourceLocation TokLoc = GetTokenLoc(I);
5183 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5184 case RangeBefore:
5185 llvm_unreachable("Infeasible");
5186 case RangeAfter:
5187 break;
5188 case RangeOverlap:
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005189 // For macro expansions, just note where the beginning of the macro
5190 // expansion occurs.
5191 if (cursor.kind == CXCursor_MacroExpansion) {
5192 if (TokLoc == cursorRange.getBegin())
5193 Cursors[I] = cursor;
5194 AdvanceToken();
5195 break;
5196 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005197 // We may have already annotated macro names inside macro definitions.
5198 if (Cursors[I].kind != CXCursor_MacroExpansion)
5199 Cursors[I] = cursor;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005200 AdvanceToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005201 continue;
5202 }
5203 break;
5204 }
5205
5206 // Save the preprocessing token index; restore the non-preprocessing
5207 // token index.
5208 PreprocessingTokIdx = TokIdx;
5209 TokIdx = SavedTokIdx;
5210 return CXChildVisit_Recurse;
5211 }
5212
5213 if (cursorRange.isInvalid())
5214 return CXChildVisit_Continue;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005215
5216 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005217 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005218 const enum CXCursorKind K = clang_getCursorKind(parent);
5219 const CXCursor updateC =
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005220 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5221 // Attributes are annotated out-of-order, skip tokens until we reach it.
5222 clang_isAttribute(cursor.kind))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005223 ? clang_getNullCursor() : parent;
5224
5225 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5226
5227 // Avoid having the cursor of an expression "overwrite" the annotation of the
5228 // variable declaration that it belongs to.
5229 // This can happen for C++ constructor expressions whose range generally
5230 // include the variable declaration, e.g.:
5231 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
5232 if (clang_isExpression(cursorK)) {
Dmitri Gribenkoff74f962013-01-26 15:29:08 +00005233 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenko404628c2013-01-26 18:12:08 +00005234 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005235 const unsigned I = NextToken();
5236 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5237 E->getLocStart() == D->getLocation() &&
5238 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005239 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005240 AdvanceToken();
5241 }
5242 }
5243 }
5244
5245 // Before recursing into the children keep some state that we are going
5246 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5247 // extra work after the child nodes are visited.
5248 // Note that we don't call VisitChildren here to avoid traversing statements
5249 // code-recursively which can blow the stack.
5250
5251 PostChildrenInfo Info;
5252 Info.Cursor = cursor;
5253 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005254 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005255 Info.BeforeChildrenTokenIdx = NextToken();
5256 PostChildrenInfos.push_back(Info);
5257
5258 return CXChildVisit_Recurse;
5259}
5260
5261bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5262 if (PostChildrenInfos.empty())
5263 return false;
5264 const PostChildrenInfo &Info = PostChildrenInfos.back();
5265 if (!clang_equalCursors(Info.Cursor, cursor))
5266 return false;
5267
5268 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5269 const unsigned AfterChildren = NextToken();
5270 SourceRange cursorRange = Info.CursorRange;
5271
5272 // Scan the tokens that are at the end of the cursor, but are not captured
5273 // but the child cursors.
5274 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5275
5276 // Scan the tokens that are at the beginning of the cursor, but are not
5277 // capture by the child cursors.
5278 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5279 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5280 break;
5281
5282 Cursors[I] = cursor;
5283 }
5284
Argyrios Kyrtzidisa86b37e2013-02-08 01:12:25 +00005285 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5286 // encountered the attribute cursor.
5287 if (clang_isAttribute(cursor.kind))
5288 TokIdx = Info.BeforeReachingCursorIdx;
5289
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005290 PostChildrenInfos.pop_back();
5291 return false;
5292}
5293
5294static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5295 CXCursor parent,
5296 CXClientData client_data) {
5297 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5298}
5299
5300static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5301 CXClientData client_data) {
5302 return static_cast<AnnotateTokensWorker*>(client_data)->
5303 postVisitChildren(cursor);
5304}
5305
5306namespace {
5307
5308/// \brief Uses the macro expansions in the preprocessing record to find
5309/// and mark tokens that are macro arguments. This info is used by the
5310/// AnnotateTokensWorker.
5311class MarkMacroArgTokensVisitor {
5312 SourceManager &SM;
5313 CXToken *Tokens;
5314 unsigned NumTokens;
5315 unsigned CurIdx;
5316
5317public:
5318 MarkMacroArgTokensVisitor(SourceManager &SM,
5319 CXToken *tokens, unsigned numTokens)
5320 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5321
5322 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5323 if (cursor.kind != CXCursor_MacroExpansion)
5324 return CXChildVisit_Continue;
5325
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00005326 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005327 if (macroRange.getBegin() == macroRange.getEnd())
5328 return CXChildVisit_Continue; // it's not a function macro.
5329
5330 for (; CurIdx < NumTokens; ++CurIdx) {
5331 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5332 macroRange.getBegin()))
5333 break;
5334 }
5335
5336 if (CurIdx == NumTokens)
5337 return CXChildVisit_Break;
5338
5339 for (; CurIdx < NumTokens; ++CurIdx) {
5340 SourceLocation tokLoc = getTokenLoc(CurIdx);
5341 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5342 break;
5343
5344 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5345 }
5346
5347 if (CurIdx == NumTokens)
5348 return CXChildVisit_Break;
5349
5350 return CXChildVisit_Continue;
5351 }
5352
5353private:
5354 SourceLocation getTokenLoc(unsigned tokI) {
5355 return SourceLocation::getFromRawEncoding(Tokens[tokI].int_data[1]);
5356 }
5357
5358 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5359 // The third field is reserved and currently not used. Use it here
5360 // to mark macro arg expanded tokens with their expanded locations.
5361 Tokens[tokI].int_data[3] = loc.getRawEncoding();
5362 }
5363};
5364
5365} // end anonymous namespace
5366
5367static CXChildVisitResult
5368MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5369 CXClientData client_data) {
5370 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5371 parent);
5372}
5373
5374namespace {
5375 struct clang_annotateTokens_Data {
5376 CXTranslationUnit TU;
5377 ASTUnit *CXXUnit;
5378 CXToken *Tokens;
5379 unsigned NumTokens;
5380 CXCursor *Cursors;
5381 };
5382}
5383
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005384/// \brief Used by \c annotatePreprocessorTokens.
5385/// \returns true if lexing was finished, false otherwise.
5386static bool lexNext(Lexer &Lex, Token &Tok,
5387 unsigned &NextIdx, unsigned NumTokens) {
5388 if (NextIdx >= NumTokens)
5389 return true;
5390
5391 ++NextIdx;
5392 Lex.LexFromRawLexer(Tok);
5393 if (Tok.is(tok::eof))
5394 return true;
5395
5396 return false;
5397}
5398
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005399static void annotatePreprocessorTokens(CXTranslationUnit TU,
5400 SourceRange RegionOfInterest,
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005401 CXCursor *Cursors,
5402 CXToken *Tokens,
5403 unsigned NumTokens) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005404 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005405
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005406 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005407 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5408 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005409 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005410 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005411 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005412
5413 if (BeginLocInfo.first != EndLocInfo.first)
5414 return;
5415
5416 StringRef Buffer;
5417 bool Invalid = false;
5418 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5419 if (Buffer.empty() || Invalid)
5420 return;
5421
5422 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5423 CXXUnit->getASTContext().getLangOpts(),
5424 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5425 Buffer.end());
5426 Lex.SetCommentRetentionState(true);
5427
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005428 unsigned NextIdx = 0;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005429 // Lex tokens in raw mode until we hit the end of the range, to avoid
5430 // entering #includes or expanding macros.
5431 while (true) {
5432 Token Tok;
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005433 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5434 break;
5435 unsigned TokIdx = NextIdx-1;
5436 assert(Tok.getLocation() ==
5437 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005438
5439 reprocess:
5440 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005441 // We have found a preprocessing directive. Annotate the tokens
5442 // appropriately.
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005443 //
5444 // FIXME: Some simple tests here could identify macro definitions and
5445 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005446
5447 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005448 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5449 break;
5450
5451 MacroInfo *MI = 0;
5452 if (Tok.is(tok::raw_identifier) &&
5453 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5454 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5455 break;
5456
5457 if (Tok.is(tok::raw_identifier)) {
5458 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5459 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5460 SourceLocation MappedTokLoc =
5461 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5462 MI = getMacroInfo(II, MappedTokLoc, TU);
5463 }
5464 }
5465
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005466 bool finished = false;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005467 do {
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005468 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5469 finished = true;
5470 break;
5471 }
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005472 // If we are in a macro definition, check if the token was ever a
5473 // macro name and annotate it if that's the case.
5474 if (MI) {
5475 SourceLocation SaveLoc = Tok.getLocation();
5476 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5477 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5478 Tok.setLocation(SaveLoc);
5479 if (MacroDef)
5480 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5481 Tok.getLocation(), TU);
5482 }
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005483 } while (!Tok.isAtStartOfLine());
5484
5485 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5486 assert(TokIdx <= LastIdx);
5487 SourceLocation EndLoc =
5488 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5489 CXCursor Cursor =
5490 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5491
5492 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis3453bf72013-01-07 19:16:32 +00005493 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005494
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005495 if (finished)
5496 break;
5497 goto reprocess;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005498 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005499 }
5500}
5501
5502// This gets run a separate thread to avoid stack blowout.
5503static void clang_annotateTokensImpl(void *UserData) {
5504 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5505 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5506 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5507 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5508 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5509
Dmitri Gribenko8c718e72013-01-26 21:49:50 +00005510 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005511 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5512 setThreadBackgroundPriority();
5513
5514 // Determine the region of interest, which contains all of the tokens.
5515 SourceRange RegionOfInterest;
5516 RegionOfInterest.setBegin(
5517 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5518 RegionOfInterest.setEnd(
5519 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5520 Tokens[NumTokens-1])));
5521
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005522 // Relex the tokens within the source range to look for preprocessing
5523 // directives.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005524 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis82064212013-02-13 18:33:28 +00005525
5526 // If begin location points inside a macro argument, set it to the expansion
5527 // location so we can have the full context when annotating semantically.
5528 {
5529 SourceManager &SM = CXXUnit->getSourceManager();
5530 SourceLocation Loc =
5531 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5532 if (Loc.isMacroID())
5533 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5534 }
5535
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005536 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5537 // Search and mark tokens that are macro argument expansions.
5538 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5539 Tokens, NumTokens);
5540 CursorVisitor MacroArgMarker(TU,
5541 MarkMacroArgTokensVisitorDelegate, &Visitor,
5542 /*VisitPreprocessorLast=*/true,
5543 /*VisitIncludedEntities=*/false,
5544 RegionOfInterest);
5545 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5546 }
5547
5548 // Annotate all of the source locations in the region of interest that map to
5549 // a specific cursor.
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00005550 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005551
5552 // FIXME: We use a ridiculous stack size here because the data-recursion
5553 // algorithm uses a large stack frame than the non-data recursive version,
5554 // and AnnotationTokensWorker currently transforms the data-recursion
5555 // algorithm back into a traditional recursion by explicitly calling
5556 // VisitChildren(). We will need to remove this explicit recursive call.
5557 W.AnnotateTokens();
5558
5559 // If we ran into any entities that involve context-sensitive keywords,
5560 // take another pass through the tokens to mark them as such.
5561 if (W.hasContextSensitiveKeywords()) {
5562 for (unsigned I = 0; I != NumTokens; ++I) {
5563 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5564 continue;
5565
5566 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5567 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005568 if (const ObjCPropertyDecl *Property
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005569 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5570 if (Property->getPropertyAttributesAsWritten() != 0 &&
5571 llvm::StringSwitch<bool>(II->getName())
5572 .Case("readonly", true)
5573 .Case("assign", true)
5574 .Case("unsafe_unretained", true)
5575 .Case("readwrite", true)
5576 .Case("retain", true)
5577 .Case("copy", true)
5578 .Case("nonatomic", true)
5579 .Case("atomic", true)
5580 .Case("getter", true)
5581 .Case("setter", true)
5582 .Case("strong", true)
5583 .Case("weak", true)
5584 .Default(false))
5585 Tokens[I].int_data[0] = CXToken_Keyword;
5586 }
5587 continue;
5588 }
5589
5590 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5591 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5592 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5593 if (llvm::StringSwitch<bool>(II->getName())
5594 .Case("in", true)
5595 .Case("out", true)
5596 .Case("inout", true)
5597 .Case("oneway", true)
5598 .Case("bycopy", true)
5599 .Case("byref", true)
5600 .Default(false))
5601 Tokens[I].int_data[0] = CXToken_Keyword;
5602 continue;
5603 }
5604
5605 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5606 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5607 Tokens[I].int_data[0] = CXToken_Keyword;
5608 continue;
5609 }
5610 }
5611 }
5612}
5613
5614extern "C" {
5615
5616void clang_annotateTokens(CXTranslationUnit TU,
5617 CXToken *Tokens, unsigned NumTokens,
5618 CXCursor *Cursors) {
Argyrios Kyrtzidis0b602832013-04-04 22:40:59 +00005619 if (!TU || NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005620 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005621 return;
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00005622 }
5623
5624 LOG_FUNC_SECTION {
5625 *Log << TU << ' ';
5626 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5627 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5628 *Log << clang_getRange(bloc, eloc);
5629 }
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005630
5631 // Any token we don't specifically annotate will have a NULL cursor.
5632 CXCursor C = clang_getNullCursor();
5633 for (unsigned I = 0; I != NumTokens; ++I)
5634 Cursors[I] = C;
5635
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00005636 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005637 if (!CXXUnit)
5638 return;
5639
5640 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5641
5642 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5643 llvm::CrashRecoveryContext CRC;
5644 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5645 GetSafetyThreadStackSize() * 2)) {
5646 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5647 }
5648}
5649
5650} // end: extern "C"
5651
5652//===----------------------------------------------------------------------===//
5653// Operations for querying linkage of a cursor.
5654//===----------------------------------------------------------------------===//
5655
5656extern "C" {
5657CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5658 if (!clang_isDeclaration(cursor.kind))
5659 return CXLinkage_Invalid;
5660
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005661 const Decl *D = cxcursor::getCursorDecl(cursor);
5662 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005663 switch (ND->getLinkage()) {
5664 case NoLinkage: return CXLinkage_NoLinkage;
5665 case InternalLinkage: return CXLinkage_Internal;
5666 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5667 case ExternalLinkage: return CXLinkage_External;
5668 };
5669
5670 return CXLinkage_Invalid;
5671}
5672} // end: extern "C"
5673
5674//===----------------------------------------------------------------------===//
5675// Operations for querying language of a cursor.
5676//===----------------------------------------------------------------------===//
5677
5678static CXLanguageKind getDeclLanguage(const Decl *D) {
5679 if (!D)
5680 return CXLanguage_C;
5681
5682 switch (D->getKind()) {
5683 default:
5684 break;
5685 case Decl::ImplicitParam:
5686 case Decl::ObjCAtDefsField:
5687 case Decl::ObjCCategory:
5688 case Decl::ObjCCategoryImpl:
5689 case Decl::ObjCCompatibleAlias:
5690 case Decl::ObjCImplementation:
5691 case Decl::ObjCInterface:
5692 case Decl::ObjCIvar:
5693 case Decl::ObjCMethod:
5694 case Decl::ObjCProperty:
5695 case Decl::ObjCPropertyImpl:
5696 case Decl::ObjCProtocol:
5697 return CXLanguage_ObjC;
5698 case Decl::CXXConstructor:
5699 case Decl::CXXConversion:
5700 case Decl::CXXDestructor:
5701 case Decl::CXXMethod:
5702 case Decl::CXXRecord:
5703 case Decl::ClassTemplate:
5704 case Decl::ClassTemplatePartialSpecialization:
5705 case Decl::ClassTemplateSpecialization:
5706 case Decl::Friend:
5707 case Decl::FriendTemplate:
5708 case Decl::FunctionTemplate:
5709 case Decl::LinkageSpec:
5710 case Decl::Namespace:
5711 case Decl::NamespaceAlias:
5712 case Decl::NonTypeTemplateParm:
5713 case Decl::StaticAssert:
5714 case Decl::TemplateTemplateParm:
5715 case Decl::TemplateTypeParm:
5716 case Decl::UnresolvedUsingTypename:
5717 case Decl::UnresolvedUsingValue:
5718 case Decl::Using:
5719 case Decl::UsingDirective:
5720 case Decl::UsingShadow:
5721 return CXLanguage_CPlusPlus;
5722 }
5723
5724 return CXLanguage_C;
5725}
5726
5727extern "C" {
5728
5729enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5730 if (clang_isDeclaration(cursor.kind))
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005731 if (const Decl *D = cxcursor::getCursorDecl(cursor)) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005732 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5733 return CXAvailability_Available;
5734
5735 switch (D->getAvailability()) {
5736 case AR_Available:
5737 case AR_NotYetIntroduced:
5738 return CXAvailability_Available;
5739
5740 case AR_Deprecated:
5741 return CXAvailability_Deprecated;
5742
5743 case AR_Unavailable:
5744 return CXAvailability_NotAvailable;
5745 }
5746 }
5747
5748 return CXAvailability_Available;
5749}
5750
5751static CXVersion convertVersion(VersionTuple In) {
5752 CXVersion Out = { -1, -1, -1 };
5753 if (In.empty())
5754 return Out;
5755
5756 Out.Major = In.getMajor();
5757
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005758 Optional<unsigned> Minor = In.getMinor();
5759 if (Minor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005760 Out.Minor = *Minor;
5761 else
5762 return Out;
5763
NAKAMURA Takumi4a3012d2013-02-21 02:32:34 +00005764 Optional<unsigned> Subminor = In.getSubminor();
5765 if (Subminor.hasValue())
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005766 Out.Subminor = *Subminor;
5767
5768 return Out;
5769}
5770
5771int clang_getCursorPlatformAvailability(CXCursor cursor,
5772 int *always_deprecated,
5773 CXString *deprecated_message,
5774 int *always_unavailable,
5775 CXString *unavailable_message,
5776 CXPlatformAvailability *availability,
5777 int availability_size) {
5778 if (always_deprecated)
5779 *always_deprecated = 0;
5780 if (deprecated_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005781 *deprecated_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005782 if (always_unavailable)
5783 *always_unavailable = 0;
5784 if (unavailable_message)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005785 *unavailable_message = cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005786
5787 if (!clang_isDeclaration(cursor.kind))
5788 return 0;
5789
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005790 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005791 if (!D)
5792 return 0;
5793
5794 int N = 0;
5795 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
5796 ++A) {
5797 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
5798 if (always_deprecated)
5799 *always_deprecated = 1;
5800 if (deprecated_message)
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005801 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005802 continue;
5803 }
5804
5805 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
5806 if (always_unavailable)
5807 *always_unavailable = 1;
5808 if (unavailable_message) {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005809 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005810 }
5811 continue;
5812 }
5813
5814 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
5815 if (N < availability_size) {
5816 availability[N].Platform
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005817 = cxstring::createDup(Avail->getPlatform()->getName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005818 availability[N].Introduced = convertVersion(Avail->getIntroduced());
5819 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
5820 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
5821 availability[N].Unavailable = Avail->getUnavailable();
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005822 availability[N].Message = cxstring::createDup(Avail->getMessage());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005823 }
5824 ++N;
5825 }
5826 }
5827
5828 return N;
5829}
5830
5831void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
5832 clang_disposeString(availability->Platform);
5833 clang_disposeString(availability->Message);
5834}
5835
5836CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
5837 if (clang_isDeclaration(cursor.kind))
5838 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
5839
5840 return CXLanguage_Invalid;
5841}
5842
5843 /// \brief If the given cursor is the "templated" declaration
5844 /// descibing a class or function template, return the class or
5845 /// function template.
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005846static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005847 if (!D)
5848 return 0;
5849
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005850 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005851 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
5852 return FunTmpl;
5853
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005854 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005855 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
5856 return ClassTmpl;
5857
5858 return D;
5859}
5860
5861CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
5862 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005863 if (const Decl *D = getCursorDecl(cursor)) {
5864 const DeclContext *DC = D->getDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005865 if (!DC)
5866 return clang_getNullCursor();
5867
5868 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5869 getCursorTU(cursor));
5870 }
5871 }
5872
5873 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005874 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005875 return MakeCXCursor(D, getCursorTU(cursor));
5876 }
5877
5878 return clang_getNullCursor();
5879}
5880
5881CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
5882 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005883 if (const Decl *D = getCursorDecl(cursor)) {
5884 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005885 if (!DC)
5886 return clang_getNullCursor();
5887
5888 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
5889 getCursorTU(cursor));
5890 }
5891 }
5892
5893 // FIXME: Note that we can't easily compute the lexical context of a
5894 // statement or expression, so we return nothing.
5895 return clang_getNullCursor();
5896}
5897
5898CXFile clang_getIncludedFile(CXCursor cursor) {
5899 if (cursor.kind != CXCursor_InclusionDirective)
5900 return 0;
5901
Dmitri Gribenko67812b22013-01-11 21:01:49 +00005902 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkoe4ea8792013-01-23 15:56:07 +00005903 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005904}
5905
5906CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
5907 if (!clang_isDeclaration(C.kind))
5908 return clang_getNullRange();
5909
5910 const Decl *D = getCursorDecl(C);
5911 ASTContext &Context = getCursorContext(C);
5912 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5913 if (!RC)
5914 return clang_getNullRange();
5915
5916 return cxloc::translateSourceRange(Context, RC->getSourceRange());
5917}
5918
5919CXString clang_Cursor_getRawCommentText(CXCursor C) {
5920 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005921 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005922
5923 const Decl *D = getCursorDecl(C);
5924 ASTContext &Context = getCursorContext(C);
5925 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5926 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
5927 StringRef();
5928
5929 // Don't duplicate the string because RawText points directly into source
5930 // code.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005931 return cxstring::createRef(RawText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005932}
5933
5934CXString clang_Cursor_getBriefCommentText(CXCursor C) {
5935 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005936 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005937
5938 const Decl *D = getCursorDecl(C);
5939 const ASTContext &Context = getCursorContext(C);
5940 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
5941
5942 if (RC) {
5943 StringRef BriefText = RC->getBriefText(Context);
5944
5945 // Don't duplicate the string because RawComment ensures that this memory
5946 // will not go away.
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005947 return cxstring::createRef(BriefText);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005948 }
5949
Dmitri Gribenkodad4c1a2013-02-01 14:13:32 +00005950 return cxstring::createNull();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005951}
5952
5953CXComment clang_Cursor_getParsedComment(CXCursor C) {
5954 if (!clang_isDeclaration(C.kind))
5955 return cxcomment::createCXComment(NULL, NULL);
5956
5957 const Decl *D = getCursorDecl(C);
5958 const ASTContext &Context = getCursorContext(C);
5959 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
5960
5961 return cxcomment::createCXComment(FC, getCursorTU(C));
5962}
5963
5964CXModule clang_Cursor_getModule(CXCursor C) {
5965 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00005966 if (const ImportDecl *ImportD =
5967 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005968 return ImportD->getImportedModule();
5969 }
5970
5971 return 0;
5972}
5973
5974CXModule clang_Module_getParent(CXModule CXMod) {
5975 if (!CXMod)
5976 return 0;
5977 Module *Mod = static_cast<Module*>(CXMod);
5978 return Mod->Parent;
5979}
5980
5981CXString clang_Module_getName(CXModule CXMod) {
5982 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005983 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005984 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005985 return cxstring::createDup(Mod->Name);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005986}
5987
5988CXString clang_Module_getFullName(CXModule CXMod) {
5989 if (!CXMod)
Dmitri Gribenkodc66adb2013-02-01 14:21:22 +00005990 return cxstring::createEmpty();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005991 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00005992 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005993}
5994
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00005995unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
5996 CXModule CXMod) {
5997 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00005998 return 0;
5999 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006000 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6001 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6002 return TopHeaders.size();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006003}
6004
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006005CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6006 CXModule CXMod, unsigned Index) {
6007 if (!TU || !CXMod)
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006008 return 0;
6009 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006010 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006011
Argyrios Kyrtzidisc1d22392013-03-13 21:13:43 +00006012 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6013 if (Index < TopHeaders.size())
6014 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006015
6016 return 0;
6017}
6018
6019} // end: extern "C"
6020
6021//===----------------------------------------------------------------------===//
6022// C++ AST instrospection.
6023//===----------------------------------------------------------------------===//
6024
6025extern "C" {
6026unsigned clang_CXXMethod_isStatic(CXCursor C) {
6027 if (!clang_isDeclaration(C.kind))
6028 return 0;
6029
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006030 const CXXMethodDecl *Method = 0;
6031 const Decl *D = cxcursor::getCursorDecl(C);
6032 if (const FunctionTemplateDecl *FunTmpl =
6033 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006034 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6035 else
6036 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6037 return (Method && Method->isStatic()) ? 1 : 0;
6038}
6039
6040unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6041 if (!clang_isDeclaration(C.kind))
6042 return 0;
6043
Dmitri Gribenkoe22339c2013-01-23 17:25:27 +00006044 const CXXMethodDecl *Method = 0;
6045 const Decl *D = cxcursor::getCursorDecl(C);
6046 if (const FunctionTemplateDecl *FunTmpl =
6047 dyn_cast_or_null<FunctionTemplateDecl>(D))
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006048 Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
6049 else
6050 Method = dyn_cast_or_null<CXXMethodDecl>(D);
6051 return (Method && Method->isVirtual()) ? 1 : 0;
6052}
6053} // end: extern "C"
6054
6055//===----------------------------------------------------------------------===//
6056// Attribute introspection.
6057//===----------------------------------------------------------------------===//
6058
6059extern "C" {
6060CXType clang_getIBOutletCollectionType(CXCursor C) {
6061 if (C.kind != CXCursor_IBOutletCollectionAttr)
6062 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6063
Dmitri Gribenko7d914382013-01-26 18:08:08 +00006064 const IBOutletCollectionAttr *A =
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006065 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6066
6067 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6068}
6069} // end: extern "C"
6070
6071//===----------------------------------------------------------------------===//
6072// Inspecting memory usage.
6073//===----------------------------------------------------------------------===//
6074
6075typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6076
6077static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6078 enum CXTUResourceUsageKind k,
6079 unsigned long amount) {
6080 CXTUResourceUsageEntry entry = { k, amount };
6081 entries.push_back(entry);
6082}
6083
6084extern "C" {
6085
6086const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6087 const char *str = "";
6088 switch (kind) {
6089 case CXTUResourceUsage_AST:
6090 str = "ASTContext: expressions, declarations, and types";
6091 break;
6092 case CXTUResourceUsage_Identifiers:
6093 str = "ASTContext: identifiers";
6094 break;
6095 case CXTUResourceUsage_Selectors:
6096 str = "ASTContext: selectors";
6097 break;
6098 case CXTUResourceUsage_GlobalCompletionResults:
6099 str = "Code completion: cached global results";
6100 break;
6101 case CXTUResourceUsage_SourceManagerContentCache:
6102 str = "SourceManager: content cache allocator";
6103 break;
6104 case CXTUResourceUsage_AST_SideTables:
6105 str = "ASTContext: side tables";
6106 break;
6107 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6108 str = "SourceManager: malloc'ed memory buffers";
6109 break;
6110 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6111 str = "SourceManager: mmap'ed memory buffers";
6112 break;
6113 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6114 str = "ExternalASTSource: malloc'ed memory buffers";
6115 break;
6116 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6117 str = "ExternalASTSource: mmap'ed memory buffers";
6118 break;
6119 case CXTUResourceUsage_Preprocessor:
6120 str = "Preprocessor: malloc'ed memory";
6121 break;
6122 case CXTUResourceUsage_PreprocessingRecord:
6123 str = "Preprocessor: PreprocessingRecord";
6124 break;
6125 case CXTUResourceUsage_SourceManager_DataStructures:
6126 str = "SourceManager: data structures and tables";
6127 break;
6128 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6129 str = "Preprocessor: header search tables";
6130 break;
6131 }
6132 return str;
6133}
6134
6135CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
6136 if (!TU) {
6137 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6138 return usage;
6139 }
6140
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006141 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006142 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6143 ASTContext &astContext = astUnit->getASTContext();
6144
6145 // How much memory is used by AST nodes and types?
6146 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6147 (unsigned long) astContext.getASTAllocatedMemory());
6148
6149 // How much memory is used by identifiers?
6150 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6151 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6152
6153 // How much memory is used for selectors?
6154 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6155 (unsigned long) astContext.Selectors.getTotalMemory());
6156
6157 // How much memory is used by ASTContext's side tables?
6158 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6159 (unsigned long) astContext.getSideTableAllocatedMemory());
6160
6161 // How much memory is used for caching global code completion results?
6162 unsigned long completionBytes = 0;
6163 if (GlobalCodeCompletionAllocator *completionAllocator =
6164 astUnit->getCachedCompletionAllocator().getPtr()) {
6165 completionBytes = completionAllocator->getTotalMemory();
6166 }
6167 createCXTUResourceUsageEntry(*entries,
6168 CXTUResourceUsage_GlobalCompletionResults,
6169 completionBytes);
6170
6171 // How much memory is being used by SourceManager's content cache?
6172 createCXTUResourceUsageEntry(*entries,
6173 CXTUResourceUsage_SourceManagerContentCache,
6174 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6175
6176 // How much memory is being used by the MemoryBuffer's in SourceManager?
6177 const SourceManager::MemoryBufferSizes &srcBufs =
6178 astUnit->getSourceManager().getMemoryBufferSizes();
6179
6180 createCXTUResourceUsageEntry(*entries,
6181 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6182 (unsigned long) srcBufs.malloc_bytes);
6183 createCXTUResourceUsageEntry(*entries,
6184 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6185 (unsigned long) srcBufs.mmap_bytes);
6186 createCXTUResourceUsageEntry(*entries,
6187 CXTUResourceUsage_SourceManager_DataStructures,
6188 (unsigned long) astContext.getSourceManager()
6189 .getDataStructureSizes());
6190
6191 // How much memory is being used by the ExternalASTSource?
6192 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6193 const ExternalASTSource::MemoryBufferSizes &sizes =
6194 esrc->getMemoryBufferSizes();
6195
6196 createCXTUResourceUsageEntry(*entries,
6197 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6198 (unsigned long) sizes.malloc_bytes);
6199 createCXTUResourceUsageEntry(*entries,
6200 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6201 (unsigned long) sizes.mmap_bytes);
6202 }
6203
6204 // How much memory is being used by the Preprocessor?
6205 Preprocessor &pp = astUnit->getPreprocessor();
6206 createCXTUResourceUsageEntry(*entries,
6207 CXTUResourceUsage_Preprocessor,
6208 pp.getTotalMemory());
6209
6210 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6211 createCXTUResourceUsageEntry(*entries,
6212 CXTUResourceUsage_PreprocessingRecord,
6213 pRec->getTotalMemory());
6214 }
6215
6216 createCXTUResourceUsageEntry(*entries,
6217 CXTUResourceUsage_Preprocessor_HeaderSearch,
6218 pp.getHeaderSearchInfo().getTotalMemory());
6219
6220 CXTUResourceUsage usage = { (void*) entries.get(),
6221 (unsigned) entries->size(),
6222 entries->size() ? &(*entries)[0] : 0 };
6223 entries.take();
6224 return usage;
6225}
6226
6227void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6228 if (usage.data)
6229 delete (MemUsageEntries*) usage.data;
6230}
6231
6232} // end extern "C"
6233
6234void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6235 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6236 for (unsigned I = 0; I != Usage.numEntries; ++I)
6237 fprintf(stderr, " %s: %lu\n",
6238 clang_getTUResourceUsageName(Usage.entries[I].kind),
6239 Usage.entries[I].amount);
6240
6241 clang_disposeCXTUResourceUsage(Usage);
6242}
6243
6244//===----------------------------------------------------------------------===//
6245// Misc. utility functions.
6246//===----------------------------------------------------------------------===//
6247
6248/// Default to using an 8 MB stack size on "safety" threads.
6249static unsigned SafetyStackThreadSize = 8 << 20;
6250
6251namespace clang {
6252
6253bool RunSafely(llvm::CrashRecoveryContext &CRC,
6254 void (*Fn)(void*), void *UserData,
6255 unsigned Size) {
6256 if (!Size)
6257 Size = GetSafetyThreadStackSize();
6258 if (Size)
6259 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6260 return CRC.RunSafely(Fn, UserData);
6261}
6262
6263unsigned GetSafetyThreadStackSize() {
6264 return SafetyStackThreadSize;
6265}
6266
6267void SetSafetyThreadStackSize(unsigned Value) {
6268 SafetyStackThreadSize = Value;
6269}
6270
6271}
6272
6273void clang::setThreadBackgroundPriority() {
6274 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6275 return;
6276
6277 // FIXME: Move to llvm/Support and make it cross-platform.
6278#ifdef __APPLE__
6279 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6280#endif
6281}
6282
6283void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6284 if (!Unit)
6285 return;
6286
6287 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6288 DEnd = Unit->stored_diag_end();
6289 D != DEnd; ++D) {
6290 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6291 CXString Msg = clang_formatDiagnostic(&Diag,
6292 clang_defaultDiagnosticDisplayOptions());
6293 fprintf(stderr, "%s\n", clang_getCString(Msg));
6294 clang_disposeString(Msg);
6295 }
6296#ifdef LLVM_ON_WIN32
6297 // On Windows, force a flush, since there may be multiple copies of
6298 // stderr and stdout in the file system, all with different buffers
6299 // but writing to the same device.
6300 fflush(stderr);
6301#endif
6302}
6303
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006304MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6305 SourceLocation MacroDefLoc,
6306 CXTranslationUnit TU){
6307 if (MacroDefLoc.isInvalid() || !TU)
6308 return 0;
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006309 if (!II.hadMacroDefinition())
6310 return 0;
6311
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006312 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidisc059f892013-01-07 19:16:30 +00006313 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006314 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006315 if (MD) {
6316 for (MacroDirective::DefInfo
6317 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6318 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6319 return Def.getMacroInfo();
6320 }
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006321 }
6322
6323 return 0;
6324}
6325
Dmitri Gribenko67812b22013-01-11 21:01:49 +00006326const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6327 CXTranslationUnit TU) {
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006328 if (!MacroDef || !TU)
6329 return 0;
6330 const IdentifierInfo *II = MacroDef->getName();
6331 if (!II)
6332 return 0;
6333
6334 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6335}
6336
6337MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6338 const Token &Tok,
6339 CXTranslationUnit TU) {
6340 if (!MI || !TU)
6341 return 0;
6342 if (Tok.isNot(tok::raw_identifier))
6343 return 0;
6344
6345 if (MI->getNumTokens() == 0)
6346 return 0;
6347 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6348 MI->getDefinitionEndLoc());
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006349 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006350
6351 // Check that the token is inside the definition and not its argument list.
6352 SourceManager &SM = Unit->getSourceManager();
6353 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6354 return 0;
6355 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6356 return 0;
6357
6358 Preprocessor &PP = Unit->getPreprocessor();
6359 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6360 if (!PPRec)
6361 return 0;
6362
6363 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6364 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6365 if (!II.hadMacroDefinition())
6366 return 0;
6367
6368 // Check that the identifier is not one of the macro arguments.
6369 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6370 return 0;
6371
Argyrios Kyrtzidis9818a1d2013-02-20 00:54:57 +00006372 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6373 if (!InnerMD)
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006374 return 0;
6375
Argyrios Kyrtzidisc56fff72013-03-26 17:17:01 +00006376 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006377}
6378
6379MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6380 SourceLocation Loc,
6381 CXTranslationUnit TU) {
6382 if (Loc.isInvalid() || !MI || !TU)
6383 return 0;
6384
6385 if (MI->getNumTokens() == 0)
6386 return 0;
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006387 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis664b06f2013-01-07 19:16:25 +00006388 Preprocessor &PP = Unit->getPreprocessor();
6389 if (!PP.getPreprocessingRecord())
6390 return 0;
6391 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6392 Token Tok;
6393 if (PP.getRawToken(Loc, Tok))
6394 return 0;
6395
6396 return checkForMacroInMacroDefinition(MI, Tok, TU);
6397}
6398
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006399extern "C" {
6400
6401CXString clang_getClangVersion() {
Dmitri Gribenko5595ded2013-02-02 02:19:29 +00006402 return cxstring::createDup(getClangFullVersion());
Guy Benyei7f92f2d2012-12-18 14:30:41 +00006403}
6404
6405} // end: extern "C"
6406
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006407Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6408 if (TU) {
Dmitri Gribenko5694feb2013-01-26 18:53:38 +00006409 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006410 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis44f65a52013-03-05 20:21:14 +00006411 if (Unit->isMainFileAST())
6412 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006413 return *this;
6414 }
6415 }
6416
6417 LogOS << "<NULL TU>";
6418 return *this;
6419}
6420
Argyrios Kyrtzidisb70e7a82013-03-08 02:32:26 +00006421Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6422 *this << FE->getName();
6423 return *this;
6424}
6425
6426Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6427 CXString cursorName = clang_getCursorDisplayName(cursor);
6428 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6429 clang_disposeString(cursorName);
6430 return *this;
6431}
6432
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006433Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6434 CXFile File;
6435 unsigned Line, Column;
6436 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6437 CXString FileName = clang_getFileName(File);
6438 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6439 clang_disposeString(FileName);
6440 return *this;
6441}
6442
6443Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6444 CXSourceLocation BLoc = clang_getRangeStart(range);
6445 CXSourceLocation ELoc = clang_getRangeEnd(range);
6446
6447 CXFile BFile;
6448 unsigned BLine, BColumn;
6449 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6450
6451 CXFile EFile;
6452 unsigned ELine, EColumn;
6453 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6454
6455 CXString BFileName = clang_getFileName(BFile);
6456 if (BFile == EFile) {
6457 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6458 BLine, BColumn, ELine, EColumn);
6459 } else {
6460 CXString EFileName = clang_getFileName(EFile);
6461 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6462 BLine, BColumn)
6463 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6464 ELine, EColumn);
6465 clang_disposeString(EFileName);
6466 }
6467 clang_disposeString(BFileName);
6468 return *this;
6469}
6470
6471Logger &cxindex::Logger::operator<<(CXString Str) {
6472 *this << clang_getCString(Str);
6473 return *this;
6474}
6475
6476Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6477 LogOS << Fmt;
6478 return *this;
6479}
6480
6481cxindex::Logger::~Logger() {
6482 LogOS.flush();
6483
6484 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6485
6486 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6487
Dmitri Gribenkocfa88f82013-01-12 19:30:44 +00006488 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisc6f5c6a2013-01-10 18:54:52 +00006489 OS << "[libclang:" << Name << ':';
6490
6491 // FIXME: Portability.
6492#if HAVE_PTHREAD_H && __APPLE__
6493 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6494 OS << tid << ':';
6495#endif
6496
6497 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6498 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6499 OS << Msg.str() << '\n';
6500
6501 if (Trace) {
6502 llvm::sys::PrintStackTrace(stderr);
6503 OS << "--------------------------------------------------\n";
6504 }
6505}