blob: 63acd0abd59865d5e52a0d06de908d2be8d6a46e [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXComment.h"
19#include "CXCursor.h"
20#include "CXSourceLocation.h"
21#include "CXString.h"
22#include "CXTranslationUnit.h"
23#include "CXType.h"
24#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000025#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000030#include "clang/Basic/Version.h"
31#include "clang/Frontend/ASTUnit.h"
32#include "clang/Frontend/CompilerInstance.h"
33#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000034#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000035#include "clang/Lex/HeaderSearch.h"
36#include "clang/Lex/Lexer.h"
37#include "clang/Lex/PreprocessingRecord.h"
38#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000039#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000040#include "llvm/ADT/Optional.h"
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/StringSwitch.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000043#include "llvm/Config/config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000044#include "llvm/Support/Compiler.h"
45#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000046#include "llvm/Support/Format.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/MemoryBuffer.h"
48#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000049#include "llvm/Support/Program.h"
50#include "llvm/Support/SaveAndRestore.h"
51#include "llvm/Support/Signals.h"
52#include "llvm/Support/Threading.h"
53#include "llvm/Support/Timer.h"
54#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000055
56#if HAVE_PTHREAD_H
57#include <pthread.h>
58#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000059
60using namespace clang;
61using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000062using namespace clang::cxtu;
63using namespace clang::cxindex;
64
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000065CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
66 if (!AU)
Guy Benyei11169dd2012-12-18 14:30:41 +000067 return 0;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000068 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000069 CXTranslationUnit D = new CXTranslationUnitImpl();
70 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000071 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000072 D->StringPool = new cxstring::CXStringPool();
Guy Benyei11169dd2012-12-18 14:30:41 +000073 D->Diagnostics = 0;
74 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Dmitri Gribenko9e605112013-11-13 22:16:51 +000075 D->CommentToXML = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +000076 return D;
77}
78
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000079bool cxtu::isASTReadError(ASTUnit *AU) {
80 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
81 DEnd = AU->stored_diag_end();
82 D != DEnd; ++D) {
83 if (D->getLevel() >= DiagnosticsEngine::Error &&
84 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
85 diag::DiagCat_AST_Deserialization_Issue)
86 return true;
87 }
88 return false;
89}
90
Guy Benyei11169dd2012-12-18 14:30:41 +000091cxtu::CXTUOwner::~CXTUOwner() {
92 if (TU)
93 clang_disposeTranslationUnit(TU);
94}
95
96/// \brief Compare two source ranges to determine their relative position in
97/// the translation unit.
98static RangeComparisonResult RangeCompare(SourceManager &SM,
99 SourceRange R1,
100 SourceRange R2) {
101 assert(R1.isValid() && "First range is invalid?");
102 assert(R2.isValid() && "Second range is invalid?");
103 if (R1.getEnd() != R2.getBegin() &&
104 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
105 return RangeBefore;
106 if (R2.getEnd() != R1.getBegin() &&
107 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
108 return RangeAfter;
109 return RangeOverlap;
110}
111
112/// \brief Determine if a source location falls within, before, or after a
113/// a given source range.
114static RangeComparisonResult LocationCompare(SourceManager &SM,
115 SourceLocation L, SourceRange R) {
116 assert(R.isValid() && "First range is invalid?");
117 assert(L.isValid() && "Second range is invalid?");
118 if (L == R.getBegin() || L == R.getEnd())
119 return RangeOverlap;
120 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
121 return RangeBefore;
122 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
123 return RangeAfter;
124 return RangeOverlap;
125}
126
127/// \brief Translate a Clang source range into a CIndex source range.
128///
129/// Clang internally represents ranges where the end location points to the
130/// start of the token at the end. However, for external clients it is more
131/// useful to have a CXSourceRange be a proper half-open interval. This routine
132/// does the appropriate translation.
133CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
134 const LangOptions &LangOpts,
135 const CharSourceRange &R) {
136 // We want the last character in this location, so we will adjust the
137 // location accordingly.
138 SourceLocation EndLoc = R.getEnd();
139 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
140 EndLoc = SM.getExpansionRange(EndLoc).second;
141 if (R.isTokenRange() && !EndLoc.isInvalid()) {
142 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
143 SM, LangOpts);
144 EndLoc = EndLoc.getLocWithOffset(Length);
145 }
146
Bill Wendlingeade3622013-01-23 08:25:41 +0000147 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000148 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000149 R.getBegin().getRawEncoding(),
150 EndLoc.getRawEncoding()
151 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000152 return Result;
153}
154
155//===----------------------------------------------------------------------===//
156// Cursor visitor.
157//===----------------------------------------------------------------------===//
158
159static SourceRange getRawCursorExtent(CXCursor C);
160static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
161
162
163RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
164 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
165}
166
167/// \brief Visit the given cursor and, if requested by the visitor,
168/// its children.
169///
170/// \param Cursor the cursor to visit.
171///
172/// \param CheckedRegionOfInterest if true, then the caller already checked
173/// that this cursor is within the region of interest.
174///
175/// \returns true if the visitation should be aborted, false if it
176/// should continue.
177bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
178 if (clang_isInvalid(Cursor.kind))
179 return false;
180
181 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000182 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000183 if (!D) {
184 assert(0 && "Invalid declaration cursor");
185 return true; // abort.
186 }
187
188 // Ignore implicit declarations, unless it's an objc method because
189 // currently we should report implicit methods for properties when indexing.
190 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
191 return false;
192 }
193
194 // If we have a range of interest, and this cursor doesn't intersect with it,
195 // we're done.
196 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
197 SourceRange Range = getRawCursorExtent(Cursor);
198 if (Range.isInvalid() || CompareRegionOfInterest(Range))
199 return false;
200 }
201
202 switch (Visitor(Cursor, Parent, ClientData)) {
203 case CXChildVisit_Break:
204 return true;
205
206 case CXChildVisit_Continue:
207 return false;
208
209 case CXChildVisit_Recurse: {
210 bool ret = VisitChildren(Cursor);
211 if (PostChildrenVisitor)
212 if (PostChildrenVisitor(Cursor, ClientData))
213 return true;
214 return ret;
215 }
216 }
217
218 llvm_unreachable("Invalid CXChildVisitResult!");
219}
220
221static bool visitPreprocessedEntitiesInRange(SourceRange R,
222 PreprocessingRecord &PPRec,
223 CursorVisitor &Visitor) {
224 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
225 FileID FID;
226
227 if (!Visitor.shouldVisitIncludedEntities()) {
228 // If the begin/end of the range lie in the same FileID, do the optimization
229 // where we skip preprocessed entities that do not come from the same FileID.
230 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
231 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
232 FID = FileID();
233 }
234
235 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
236 Entities = PPRec.getPreprocessedEntitiesInRange(R);
237 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
238 PPRec, FID);
239}
240
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000241bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000242 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000243 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000244
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000245 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 SourceManager &SM = Unit->getSourceManager();
247
248 std::pair<FileID, unsigned>
249 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
250 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
251
252 if (End.first != Begin.first) {
253 // If the end does not reside in the same file, try to recover by
254 // picking the end of the file of begin location.
255 End.first = Begin.first;
256 End.second = SM.getFileIDSize(Begin.first);
257 }
258
259 assert(Begin.first == End.first);
260 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000261 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000262
263 FileID File = Begin.first;
264 unsigned Offset = Begin.second;
265 unsigned Length = End.second - Begin.second;
266
267 if (!VisitDeclsOnly && !VisitPreprocessorLast)
268 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000271 if (visitDeclsFromFileRegion(File, Offset, Length))
272 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000273
274 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000275 return visitPreprocessedEntitiesInRegion();
276
277 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000278}
279
280static bool isInLexicalContext(Decl *D, DeclContext *DC) {
281 if (!DC)
282 return false;
283
284 for (DeclContext *DeclDC = D->getLexicalDeclContext();
285 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
286 if (DeclDC == DC)
287 return true;
288 }
289 return false;
290}
291
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000292bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000293 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000294 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000295 SourceManager &SM = Unit->getSourceManager();
296 SourceRange Range = RegionOfInterest;
297
298 SmallVector<Decl *, 16> Decls;
299 Unit->findFileRegionDecls(File, Offset, Length, Decls);
300
301 // If we didn't find any file level decls for the file, try looking at the
302 // file that it was included from.
303 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
304 bool Invalid = false;
305 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
306 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000307 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000308
309 SourceLocation Outer;
310 if (SLEntry.isFile())
311 Outer = SLEntry.getFile().getIncludeLoc();
312 else
313 Outer = SLEntry.getExpansion().getExpansionLocStart();
314 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
317 llvm::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
318 Length = 0;
319 Unit->findFileRegionDecls(File, Offset, Length, Decls);
320 }
321
322 assert(!Decls.empty());
323
324 bool VisitedAtLeastOnce = false;
325 DeclContext *CurDC = 0;
Craig Topper2341c0d2013-07-04 03:08:24 +0000326 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
327 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000328 Decl *D = *DIt;
329 if (D->getSourceRange().isInvalid())
330 continue;
331
332 if (isInLexicalContext(D, CurDC))
333 continue;
334
335 CurDC = dyn_cast<DeclContext>(D);
336
337 if (TagDecl *TD = dyn_cast<TagDecl>(D))
338 if (!TD->isFreeStanding())
339 continue;
340
341 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
342 if (CompRes == RangeBefore)
343 continue;
344 if (CompRes == RangeAfter)
345 break;
346
347 assert(CompRes == RangeOverlap);
348 VisitedAtLeastOnce = true;
349
350 if (isa<ObjCContainerDecl>(D)) {
351 FileDI_current = &DIt;
352 FileDE_current = DE;
353 } else {
354 FileDI_current = 0;
355 }
356
357 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000358 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000359 }
360
361 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000362 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363
364 // No Decls overlapped with the range. Move up the lexical context until there
365 // is a context that contains the range or we reach the translation unit
366 // level.
367 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
368 : (*(DIt-1))->getLexicalDeclContext();
369
370 while (DC && !DC->isTranslationUnit()) {
371 Decl *D = cast<Decl>(DC);
372 SourceRange CurDeclRange = D->getSourceRange();
373 if (CurDeclRange.isInvalid())
374 break;
375
376 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000377 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
378 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000379 }
380
381 DC = D->getLexicalDeclContext();
382 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000383
384 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000385}
386
387bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
388 if (!AU->getPreprocessor().getPreprocessingRecord())
389 return false;
390
391 PreprocessingRecord &PPRec
392 = *AU->getPreprocessor().getPreprocessingRecord();
393 SourceManager &SM = AU->getSourceManager();
394
395 if (RegionOfInterest.isValid()) {
396 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
397 SourceLocation B = MappedRange.getBegin();
398 SourceLocation E = MappedRange.getEnd();
399
400 if (AU->isInPreambleFileID(B)) {
401 if (SM.isLoadedSourceLocation(E))
402 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
403 PPRec, *this);
404
405 // Beginning of range lies in the preamble but it also extends beyond
406 // it into the main file. Split the range into 2 parts, one covering
407 // the preamble and another covering the main file. This allows subsequent
408 // calls to visitPreprocessedEntitiesInRange to accept a source range that
409 // lies in the same FileID, allowing it to skip preprocessed entities that
410 // do not come from the same FileID.
411 bool breaked =
412 visitPreprocessedEntitiesInRange(
413 SourceRange(B, AU->getEndOfPreambleFileID()),
414 PPRec, *this);
415 if (breaked) return true;
416 return visitPreprocessedEntitiesInRange(
417 SourceRange(AU->getStartOfMainFileID(), E),
418 PPRec, *this);
419 }
420
421 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
422 }
423
424 bool OnlyLocalDecls
425 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
426
427 if (OnlyLocalDecls)
428 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
429 PPRec);
430
431 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
432}
433
434template<typename InputIterator>
435bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
436 InputIterator Last,
437 PreprocessingRecord &PPRec,
438 FileID FID) {
439 for (; First != Last; ++First) {
440 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
441 continue;
442
443 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000444 if (!PPE)
445 continue;
446
Guy Benyei11169dd2012-12-18 14:30:41 +0000447 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
448 if (Visit(MakeMacroExpansionCursor(ME, TU)))
449 return true;
450
451 continue;
452 }
453
454 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
455 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
456 return true;
457
458 continue;
459 }
460
461 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
462 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
463 return true;
464
465 continue;
466 }
467 }
468
469 return false;
470}
471
472/// \brief Visit the children of the given cursor.
473///
474/// \returns true if the visitation should be aborted, false if it
475/// should continue.
476bool CursorVisitor::VisitChildren(CXCursor Cursor) {
477 if (clang_isReference(Cursor.kind) &&
478 Cursor.kind != CXCursor_CXXBaseSpecifier) {
479 // By definition, references have no children.
480 return false;
481 }
482
483 // Set the Parent field to Cursor, then back to its old value once we're
484 // done.
485 SetParentRAII SetParent(Parent, StmtParent, Cursor);
486
487 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000488 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000489 if (!D)
490 return false;
491
492 return VisitAttributes(D) || Visit(D);
493 }
494
495 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000496 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 return Visit(S);
498
499 return false;
500 }
501
502 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000503 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000504 return Visit(E);
505
506 return false;
507 }
508
509 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000510 CXTranslationUnit TU = getCursorTU(Cursor);
511 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000512
513 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
514 for (unsigned I = 0; I != 2; ++I) {
515 if (VisitOrder[I]) {
516 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
517 RegionOfInterest.isInvalid()) {
518 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
519 TLEnd = CXXUnit->top_level_end();
520 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000521 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000522 return true;
523 }
524 } else if (VisitDeclContext(
525 CXXUnit->getASTContext().getTranslationUnitDecl()))
526 return true;
527 continue;
528 }
529
530 // Walk the preprocessing record.
531 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
532 visitPreprocessedEntitiesInRegion();
533 }
534
535 return false;
536 }
537
538 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000539 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000540 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
541 return Visit(BaseTSInfo->getTypeLoc());
542 }
543 }
544 }
545
546 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000547 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000549 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000550 return Visit(cxcursor::MakeCursorObjCClassRef(
551 ObjT->getInterface(),
552 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000553 }
554
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000555 // If pointing inside a macro definition, check if the token is an identifier
556 // that was ever defined as a macro. In such a case, create a "pseudo" macro
557 // expansion cursor for that token.
558 SourceLocation BeginLoc = RegionOfInterest.getBegin();
559 if (Cursor.kind == CXCursor_MacroDefinition &&
560 BeginLoc == RegionOfInterest.getEnd()) {
561 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000562 const MacroInfo *MI =
563 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000564 if (MacroDefinition *MacroDef =
565 checkForMacroInMacroDefinition(MI, Loc, TU))
566 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
567 }
568
Guy Benyei11169dd2012-12-18 14:30:41 +0000569 // Nothing to visit at the moment.
570 return false;
571}
572
573bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
574 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
575 if (Visit(TSInfo->getTypeLoc()))
576 return true;
577
578 if (Stmt *Body = B->getBody())
579 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
580
581 return false;
582}
583
Ted Kremenek03325582013-02-21 01:29:01 +0000584Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000585 if (RegionOfInterest.isValid()) {
586 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
587 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000588 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000589
590 switch (CompareRegionOfInterest(Range)) {
591 case RangeBefore:
592 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000593 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000594
595 case RangeAfter:
596 // This declaration comes after the region of interest; we're done.
597 return false;
598
599 case RangeOverlap:
600 // This declaration overlaps the region of interest; visit it.
601 break;
602 }
603 }
604 return true;
605}
606
607bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
608 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
609
610 // FIXME: Eventually remove. This part of a hack to support proper
611 // iteration over all Decls contained lexically within an ObjC container.
612 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
613 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
614
615 for ( ; I != E; ++I) {
616 Decl *D = *I;
617 if (D->getLexicalDeclContext() != DC)
618 continue;
619 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
620
621 // Ignore synthesized ivars here, otherwise if we have something like:
622 // @synthesize prop = _prop;
623 // and '_prop' is not declared, we will encounter a '_prop' ivar before
624 // encountering the 'prop' synthesize declaration and we will think that
625 // we passed the region-of-interest.
626 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
627 if (ivarD->getSynthesize())
628 continue;
629 }
630
631 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
632 // declarations is a mismatch with the compiler semantics.
633 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
634 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
635 if (!ID->isThisDeclarationADefinition())
636 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
637
638 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
639 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
640 if (!PD->isThisDeclarationADefinition())
641 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
642 }
643
Ted Kremenek03325582013-02-21 01:29:01 +0000644 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000645 if (!V.hasValue())
646 continue;
647 if (!V.getValue())
648 return false;
649 if (Visit(Cursor, true))
650 return true;
651 }
652 return false;
653}
654
655bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
656 llvm_unreachable("Translation units are visited directly by Visit()");
657}
658
659bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
660 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
661 return Visit(TSInfo->getTypeLoc());
662
663 return false;
664}
665
666bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
667 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
668 return Visit(TSInfo->getTypeLoc());
669
670 return false;
671}
672
673bool CursorVisitor::VisitTagDecl(TagDecl *D) {
674 return VisitDeclContext(D);
675}
676
677bool CursorVisitor::VisitClassTemplateSpecializationDecl(
678 ClassTemplateSpecializationDecl *D) {
679 bool ShouldVisitBody = false;
680 switch (D->getSpecializationKind()) {
681 case TSK_Undeclared:
682 case TSK_ImplicitInstantiation:
683 // Nothing to visit
684 return false;
685
686 case TSK_ExplicitInstantiationDeclaration:
687 case TSK_ExplicitInstantiationDefinition:
688 break;
689
690 case TSK_ExplicitSpecialization:
691 ShouldVisitBody = true;
692 break;
693 }
694
695 // Visit the template arguments used in the specialization.
696 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
697 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000698 if (TemplateSpecializationTypeLoc TSTLoc =
699 TL.getAs<TemplateSpecializationTypeLoc>()) {
700 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
701 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000702 return true;
703 }
704 }
705
706 if (ShouldVisitBody && VisitCXXRecordDecl(D))
707 return true;
708
709 return false;
710}
711
712bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
713 ClassTemplatePartialSpecializationDecl *D) {
714 // FIXME: Visit the "outer" template parameter lists on the TagDecl
715 // before visiting these template parameters.
716 if (VisitTemplateParameters(D->getTemplateParameters()))
717 return true;
718
719 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000720 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
721 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
722 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000723 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
724 return true;
725
726 return VisitCXXRecordDecl(D);
727}
728
729bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
730 // Visit the default argument.
731 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
732 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
733 if (Visit(DefArg->getTypeLoc()))
734 return true;
735
736 return false;
737}
738
739bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
740 if (Expr *Init = D->getInitExpr())
741 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
742 return false;
743}
744
745bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000746 unsigned NumParamList = DD->getNumTemplateParameterLists();
747 for (unsigned i = 0; i < NumParamList; i++) {
748 TemplateParameterList* Params = DD->getTemplateParameterList(i);
749 if (VisitTemplateParameters(Params))
750 return true;
751 }
752
Guy Benyei11169dd2012-12-18 14:30:41 +0000753 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
754 if (Visit(TSInfo->getTypeLoc()))
755 return true;
756
757 // Visit the nested-name-specifier, if present.
758 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
759 if (VisitNestedNameSpecifierLoc(QualifierLoc))
760 return true;
761
762 return false;
763}
764
765/// \brief Compare two base or member initializers based on their source order.
Benjamin Kramer04bf1872013-09-22 14:10:29 +0000766static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
767 CXXCtorInitializer *const *Y) {
768 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
Guy Benyei11169dd2012-12-18 14:30:41 +0000769}
770
771bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000772 unsigned NumParamList = ND->getNumTemplateParameterLists();
773 for (unsigned i = 0; i < NumParamList; i++) {
774 TemplateParameterList* Params = ND->getTemplateParameterList(i);
775 if (VisitTemplateParameters(Params))
776 return true;
777 }
778
Guy Benyei11169dd2012-12-18 14:30:41 +0000779 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
780 // Visit the function declaration's syntactic components in the order
781 // written. This requires a bit of work.
782 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000783 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000784
785 // If we have a function declared directly (without the use of a typedef),
786 // visit just the return type. Otherwise, just visit the function's type
787 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000788 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000789 (!FTL && Visit(TL)))
790 return true;
791
792 // Visit the nested-name-specifier, if present.
793 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
794 if (VisitNestedNameSpecifierLoc(QualifierLoc))
795 return true;
796
797 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000798 if (!isa<CXXDestructorDecl>(ND))
799 if (VisitDeclarationNameInfo(ND->getNameInfo()))
800 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000801
802 // FIXME: Visit explicitly-specified template arguments!
803
804 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000805 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000806 return true;
807
Bill Wendling44426052012-12-20 19:22:21 +0000808 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000809 }
810
811 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
812 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
813 // Find the initializers that were written in the source.
814 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
815 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
816 IEnd = Constructor->init_end();
817 I != IEnd; ++I) {
818 if (!(*I)->isWritten())
819 continue;
820
821 WrittenInits.push_back(*I);
822 }
823
824 // Sort the initializers in source order
825 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
826 &CompareCXXCtorInitializers);
827
828 // Visit the initializers in source order
829 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
830 CXXCtorInitializer *Init = WrittenInits[I];
831 if (Init->isAnyMemberInitializer()) {
832 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
833 Init->getMemberLocation(), TU)))
834 return true;
835 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
836 if (Visit(TInfo->getTypeLoc()))
837 return true;
838 }
839
840 // Visit the initializer value.
841 if (Expr *Initializer = Init->getInit())
842 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
843 return true;
844 }
845 }
846
847 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
848 return true;
849 }
850
851 return false;
852}
853
854bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
855 if (VisitDeclaratorDecl(D))
856 return true;
857
858 if (Expr *BitWidth = D->getBitWidth())
859 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
860
861 return false;
862}
863
864bool CursorVisitor::VisitVarDecl(VarDecl *D) {
865 if (VisitDeclaratorDecl(D))
866 return true;
867
868 if (Expr *Init = D->getInit())
869 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
870
871 return false;
872}
873
874bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
875 if (VisitDeclaratorDecl(D))
876 return true;
877
878 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
879 if (Expr *DefArg = D->getDefaultArgument())
880 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
881
882 return false;
883}
884
885bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
886 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
887 // before visiting these template parameters.
888 if (VisitTemplateParameters(D->getTemplateParameters()))
889 return true;
890
891 return VisitFunctionDecl(D->getTemplatedDecl());
892}
893
894bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
895 // FIXME: Visit the "outer" template parameter lists on the TagDecl
896 // before visiting these template parameters.
897 if (VisitTemplateParameters(D->getTemplateParameters()))
898 return true;
899
900 return VisitCXXRecordDecl(D->getTemplatedDecl());
901}
902
903bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
904 if (VisitTemplateParameters(D->getTemplateParameters()))
905 return true;
906
907 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
908 VisitTemplateArgumentLoc(D->getDefaultArgument()))
909 return true;
910
911 return false;
912}
913
914bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000915 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000916 if (Visit(TSInfo->getTypeLoc()))
917 return true;
918
919 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
920 PEnd = ND->param_end();
921 P != PEnd; ++P) {
922 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
923 return true;
924 }
925
926 if (ND->isThisDeclarationADefinition() &&
927 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
928 return true;
929
930 return false;
931}
932
933template <typename DeclIt>
934static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
935 SourceManager &SM, SourceLocation EndLoc,
936 SmallVectorImpl<Decl *> &Decls) {
937 DeclIt next = *DI_current;
938 while (++next != DE_current) {
939 Decl *D_next = *next;
940 if (!D_next)
941 break;
942 SourceLocation L = D_next->getLocStart();
943 if (!L.isValid())
944 break;
945 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
946 *DI_current = next;
947 Decls.push_back(D_next);
948 continue;
949 }
950 break;
951 }
952}
953
954namespace {
955 struct ContainerDeclsSort {
956 SourceManager &SM;
957 ContainerDeclsSort(SourceManager &sm) : SM(sm) {}
958 bool operator()(Decl *A, Decl *B) {
959 SourceLocation L_A = A->getLocStart();
960 SourceLocation L_B = B->getLocStart();
961 assert(L_A.isValid() && L_B.isValid());
962 return SM.isBeforeInTranslationUnit(L_A, L_B);
963 }
964 };
965}
966
967bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
968 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
969 // an @implementation can lexically contain Decls that are not properly
970 // nested in the AST. When we identify such cases, we need to retrofit
971 // this nesting here.
972 if (!DI_current && !FileDI_current)
973 return VisitDeclContext(D);
974
975 // Scan the Decls that immediately come after the container
976 // in the current DeclContext. If any fall within the
977 // container's lexical region, stash them into a vector
978 // for later processing.
979 SmallVector<Decl *, 24> DeclsInContainer;
980 SourceLocation EndLoc = D->getSourceRange().getEnd();
981 SourceManager &SM = AU->getSourceManager();
982 if (EndLoc.isValid()) {
983 if (DI_current) {
984 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
985 DeclsInContainer);
986 } else {
987 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
988 DeclsInContainer);
989 }
990 }
991
992 // The common case.
993 if (DeclsInContainer.empty())
994 return VisitDeclContext(D);
995
996 // Get all the Decls in the DeclContext, and sort them with the
997 // additional ones we've collected. Then visit them.
998 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
999 I!=E; ++I) {
1000 Decl *subDecl = *I;
1001 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
1002 subDecl->getLocStart().isInvalid())
1003 continue;
1004 DeclsInContainer.push_back(subDecl);
1005 }
1006
1007 // Now sort the Decls so that they appear in lexical order.
1008 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
1009 ContainerDeclsSort(SM));
1010
1011 // Now visit the decls.
1012 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1013 E = DeclsInContainer.end(); I != E; ++I) {
1014 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001015 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001016 if (!V.hasValue())
1017 continue;
1018 if (!V.getValue())
1019 return false;
1020 if (Visit(Cursor, true))
1021 return true;
1022 }
1023 return false;
1024}
1025
1026bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1027 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1028 TU)))
1029 return true;
1030
1031 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1032 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1033 E = ND->protocol_end(); I != E; ++I, ++PL)
1034 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1035 return true;
1036
1037 return VisitObjCContainerDecl(ND);
1038}
1039
1040bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1041 if (!PID->isThisDeclarationADefinition())
1042 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1043
1044 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1045 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1046 E = PID->protocol_end(); I != E; ++I, ++PL)
1047 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1048 return true;
1049
1050 return VisitObjCContainerDecl(PID);
1051}
1052
1053bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1054 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1055 return true;
1056
1057 // FIXME: This implements a workaround with @property declarations also being
1058 // installed in the DeclContext for the @interface. Eventually this code
1059 // should be removed.
1060 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1061 if (!CDecl || !CDecl->IsClassExtension())
1062 return false;
1063
1064 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1065 if (!ID)
1066 return false;
1067
1068 IdentifierInfo *PropertyId = PD->getIdentifier();
1069 ObjCPropertyDecl *prevDecl =
1070 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1071
1072 if (!prevDecl)
1073 return false;
1074
1075 // Visit synthesized methods since they will be skipped when visiting
1076 // the @interface.
1077 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1078 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1079 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1080 return true;
1081
1082 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1083 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1084 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1085 return true;
1086
1087 return false;
1088}
1089
1090bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1091 if (!D->isThisDeclarationADefinition()) {
1092 // Forward declaration is treated like a reference.
1093 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1094 }
1095
1096 // Issue callbacks for super class.
1097 if (D->getSuperClass() &&
1098 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1099 D->getSuperClassLoc(),
1100 TU)))
1101 return true;
1102
1103 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1104 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1105 E = D->protocol_end(); I != E; ++I, ++PL)
1106 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1107 return true;
1108
1109 return VisitObjCContainerDecl(D);
1110}
1111
1112bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1113 return VisitObjCContainerDecl(D);
1114}
1115
1116bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1117 // 'ID' could be null when dealing with invalid code.
1118 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1119 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1120 return true;
1121
1122 return VisitObjCImplDecl(D);
1123}
1124
1125bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1126#if 0
1127 // Issue callbacks for super class.
1128 // FIXME: No source location information!
1129 if (D->getSuperClass() &&
1130 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1131 D->getSuperClassLoc(),
1132 TU)))
1133 return true;
1134#endif
1135
1136 return VisitObjCImplDecl(D);
1137}
1138
1139bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1140 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1141 if (PD->isIvarNameSpecified())
1142 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1143
1144 return false;
1145}
1146
1147bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1148 return VisitDeclContext(D);
1149}
1150
1151bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1152 // Visit nested-name-specifier.
1153 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1154 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1155 return true;
1156
1157 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1158 D->getTargetNameLoc(), TU));
1159}
1160
1161bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1162 // Visit nested-name-specifier.
1163 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1164 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1165 return true;
1166 }
1167
1168 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1169 return true;
1170
1171 return VisitDeclarationNameInfo(D->getNameInfo());
1172}
1173
1174bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1175 // Visit nested-name-specifier.
1176 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1177 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1178 return true;
1179
1180 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1181 D->getIdentLocation(), TU));
1182}
1183
1184bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1185 // Visit nested-name-specifier.
1186 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1187 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1188 return true;
1189 }
1190
1191 return VisitDeclarationNameInfo(D->getNameInfo());
1192}
1193
1194bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1195 UnresolvedUsingTypenameDecl *D) {
1196 // Visit nested-name-specifier.
1197 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1198 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1199 return true;
1200
1201 return false;
1202}
1203
1204bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1205 switch (Name.getName().getNameKind()) {
1206 case clang::DeclarationName::Identifier:
1207 case clang::DeclarationName::CXXLiteralOperatorName:
1208 case clang::DeclarationName::CXXOperatorName:
1209 case clang::DeclarationName::CXXUsingDirective:
1210 return false;
1211
1212 case clang::DeclarationName::CXXConstructorName:
1213 case clang::DeclarationName::CXXDestructorName:
1214 case clang::DeclarationName::CXXConversionFunctionName:
1215 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1216 return Visit(TSInfo->getTypeLoc());
1217 return false;
1218
1219 case clang::DeclarationName::ObjCZeroArgSelector:
1220 case clang::DeclarationName::ObjCOneArgSelector:
1221 case clang::DeclarationName::ObjCMultiArgSelector:
1222 // FIXME: Per-identifier location info?
1223 return false;
1224 }
1225
1226 llvm_unreachable("Invalid DeclarationName::Kind!");
1227}
1228
1229bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1230 SourceRange Range) {
1231 // FIXME: This whole routine is a hack to work around the lack of proper
1232 // source information in nested-name-specifiers (PR5791). Since we do have
1233 // a beginning source location, we can visit the first component of the
1234 // nested-name-specifier, if it's a single-token component.
1235 if (!NNS)
1236 return false;
1237
1238 // Get the first component in the nested-name-specifier.
1239 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1240 NNS = Prefix;
1241
1242 switch (NNS->getKind()) {
1243 case NestedNameSpecifier::Namespace:
1244 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1245 TU));
1246
1247 case NestedNameSpecifier::NamespaceAlias:
1248 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1249 Range.getBegin(), TU));
1250
1251 case NestedNameSpecifier::TypeSpec: {
1252 // If the type has a form where we know that the beginning of the source
1253 // range matches up with a reference cursor. Visit the appropriate reference
1254 // cursor.
1255 const Type *T = NNS->getAsType();
1256 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1257 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1258 if (const TagType *Tag = dyn_cast<TagType>(T))
1259 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1260 if (const TemplateSpecializationType *TST
1261 = dyn_cast<TemplateSpecializationType>(T))
1262 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1263 break;
1264 }
1265
1266 case NestedNameSpecifier::TypeSpecWithTemplate:
1267 case NestedNameSpecifier::Global:
1268 case NestedNameSpecifier::Identifier:
1269 break;
1270 }
1271
1272 return false;
1273}
1274
1275bool
1276CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1277 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1278 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1279 Qualifiers.push_back(Qualifier);
1280
1281 while (!Qualifiers.empty()) {
1282 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1283 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1284 switch (NNS->getKind()) {
1285 case NestedNameSpecifier::Namespace:
1286 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1287 Q.getLocalBeginLoc(),
1288 TU)))
1289 return true;
1290
1291 break;
1292
1293 case NestedNameSpecifier::NamespaceAlias:
1294 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1295 Q.getLocalBeginLoc(),
1296 TU)))
1297 return true;
1298
1299 break;
1300
1301 case NestedNameSpecifier::TypeSpec:
1302 case NestedNameSpecifier::TypeSpecWithTemplate:
1303 if (Visit(Q.getTypeLoc()))
1304 return true;
1305
1306 break;
1307
1308 case NestedNameSpecifier::Global:
1309 case NestedNameSpecifier::Identifier:
1310 break;
1311 }
1312 }
1313
1314 return false;
1315}
1316
1317bool CursorVisitor::VisitTemplateParameters(
1318 const TemplateParameterList *Params) {
1319 if (!Params)
1320 return false;
1321
1322 for (TemplateParameterList::const_iterator P = Params->begin(),
1323 PEnd = Params->end();
1324 P != PEnd; ++P) {
1325 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1326 return true;
1327 }
1328
1329 return false;
1330}
1331
1332bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1333 switch (Name.getKind()) {
1334 case TemplateName::Template:
1335 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1336
1337 case TemplateName::OverloadedTemplate:
1338 // Visit the overloaded template set.
1339 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1340 return true;
1341
1342 return false;
1343
1344 case TemplateName::DependentTemplate:
1345 // FIXME: Visit nested-name-specifier.
1346 return false;
1347
1348 case TemplateName::QualifiedTemplate:
1349 // FIXME: Visit nested-name-specifier.
1350 return Visit(MakeCursorTemplateRef(
1351 Name.getAsQualifiedTemplateName()->getDecl(),
1352 Loc, TU));
1353
1354 case TemplateName::SubstTemplateTemplateParm:
1355 return Visit(MakeCursorTemplateRef(
1356 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1357 Loc, TU));
1358
1359 case TemplateName::SubstTemplateTemplateParmPack:
1360 return Visit(MakeCursorTemplateRef(
1361 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1362 Loc, TU));
1363 }
1364
1365 llvm_unreachable("Invalid TemplateName::Kind!");
1366}
1367
1368bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1369 switch (TAL.getArgument().getKind()) {
1370 case TemplateArgument::Null:
1371 case TemplateArgument::Integral:
1372 case TemplateArgument::Pack:
1373 return false;
1374
1375 case TemplateArgument::Type:
1376 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1377 return Visit(TSInfo->getTypeLoc());
1378 return false;
1379
1380 case TemplateArgument::Declaration:
1381 if (Expr *E = TAL.getSourceDeclExpression())
1382 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1383 return false;
1384
1385 case TemplateArgument::NullPtr:
1386 if (Expr *E = TAL.getSourceNullPtrExpression())
1387 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1388 return false;
1389
1390 case TemplateArgument::Expression:
1391 if (Expr *E = TAL.getSourceExpression())
1392 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1393 return false;
1394
1395 case TemplateArgument::Template:
1396 case TemplateArgument::TemplateExpansion:
1397 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1398 return true;
1399
1400 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1401 TAL.getTemplateNameLoc());
1402 }
1403
1404 llvm_unreachable("Invalid TemplateArgument::Kind!");
1405}
1406
1407bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1408 return VisitDeclContext(D);
1409}
1410
1411bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1412 return Visit(TL.getUnqualifiedLoc());
1413}
1414
1415bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1416 ASTContext &Context = AU->getASTContext();
1417
1418 // Some builtin types (such as Objective-C's "id", "sel", and
1419 // "Class") have associated declarations. Create cursors for those.
1420 QualType VisitType;
1421 switch (TL.getTypePtr()->getKind()) {
1422
1423 case BuiltinType::Void:
1424 case BuiltinType::NullPtr:
1425 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001426 case BuiltinType::OCLImage1d:
1427 case BuiltinType::OCLImage1dArray:
1428 case BuiltinType::OCLImage1dBuffer:
1429 case BuiltinType::OCLImage2d:
1430 case BuiltinType::OCLImage2dArray:
1431 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001432 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001433 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001434#define BUILTIN_TYPE(Id, SingletonId)
1435#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1436#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1437#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1438#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1439#include "clang/AST/BuiltinTypes.def"
1440 break;
1441
1442 case BuiltinType::ObjCId:
1443 VisitType = Context.getObjCIdType();
1444 break;
1445
1446 case BuiltinType::ObjCClass:
1447 VisitType = Context.getObjCClassType();
1448 break;
1449
1450 case BuiltinType::ObjCSel:
1451 VisitType = Context.getObjCSelType();
1452 break;
1453 }
1454
1455 if (!VisitType.isNull()) {
1456 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1457 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1458 TU));
1459 }
1460
1461 return false;
1462}
1463
1464bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1465 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1466}
1467
1468bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1469 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1470}
1471
1472bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1473 if (TL.isDefinition())
1474 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1475
1476 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1477}
1478
1479bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1480 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1481}
1482
1483bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1484 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1485 return true;
1486
1487 return false;
1488}
1489
1490bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1491 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1492 return true;
1493
1494 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1495 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1496 TU)))
1497 return true;
1498 }
1499
1500 return false;
1501}
1502
1503bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1504 return Visit(TL.getPointeeLoc());
1505}
1506
1507bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1508 return Visit(TL.getInnerLoc());
1509}
1510
1511bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1512 return Visit(TL.getPointeeLoc());
1513}
1514
1515bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1516 return Visit(TL.getPointeeLoc());
1517}
1518
1519bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1520 return Visit(TL.getPointeeLoc());
1521}
1522
1523bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1524 return Visit(TL.getPointeeLoc());
1525}
1526
1527bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1528 return Visit(TL.getPointeeLoc());
1529}
1530
1531bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1532 return Visit(TL.getModifiedLoc());
1533}
1534
1535bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1536 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001537 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001538 return true;
1539
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001540 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1541 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001542 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1543 return true;
1544
1545 return false;
1546}
1547
1548bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1549 if (Visit(TL.getElementLoc()))
1550 return true;
1551
1552 if (Expr *Size = TL.getSizeExpr())
1553 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1554
1555 return false;
1556}
1557
Reid Kleckner8a365022013-06-24 17:51:48 +00001558bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1559 return Visit(TL.getOriginalLoc());
1560}
1561
Reid Kleckner0503a872013-12-05 01:23:43 +00001562bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1563 return Visit(TL.getOriginalLoc());
1564}
1565
Guy Benyei11169dd2012-12-18 14:30:41 +00001566bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1567 TemplateSpecializationTypeLoc TL) {
1568 // Visit the template name.
1569 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1570 TL.getTemplateNameLoc()))
1571 return true;
1572
1573 // Visit the template arguments.
1574 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1575 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1576 return true;
1577
1578 return false;
1579}
1580
1581bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1582 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1583}
1584
1585bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1586 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1587 return Visit(TSInfo->getTypeLoc());
1588
1589 return false;
1590}
1591
1592bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1593 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1594 return Visit(TSInfo->getTypeLoc());
1595
1596 return false;
1597}
1598
1599bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1600 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1601 return true;
1602
1603 return false;
1604}
1605
1606bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1607 DependentTemplateSpecializationTypeLoc TL) {
1608 // Visit the nested-name-specifier, if there is one.
1609 if (TL.getQualifierLoc() &&
1610 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1611 return true;
1612
1613 // Visit the template arguments.
1614 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1615 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1616 return true;
1617
1618 return false;
1619}
1620
1621bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1622 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1623 return true;
1624
1625 return Visit(TL.getNamedTypeLoc());
1626}
1627
1628bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1629 return Visit(TL.getPatternLoc());
1630}
1631
1632bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1633 if (Expr *E = TL.getUnderlyingExpr())
1634 return Visit(MakeCXCursor(E, StmtParent, TU));
1635
1636 return false;
1637}
1638
1639bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1640 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1641}
1642
1643bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1644 return Visit(TL.getValueLoc());
1645}
1646
1647#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1648bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1649 return Visit##PARENT##Loc(TL); \
1650}
1651
1652DEFAULT_TYPELOC_IMPL(Complex, Type)
1653DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1654DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1655DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1656DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1657DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1658DEFAULT_TYPELOC_IMPL(Vector, Type)
1659DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1660DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1661DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1662DEFAULT_TYPELOC_IMPL(Record, TagType)
1663DEFAULT_TYPELOC_IMPL(Enum, TagType)
1664DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1665DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1666DEFAULT_TYPELOC_IMPL(Auto, Type)
1667
1668bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1669 // Visit the nested-name-specifier, if present.
1670 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1671 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1672 return true;
1673
1674 if (D->isCompleteDefinition()) {
1675 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1676 E = D->bases_end(); I != E; ++I) {
1677 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1678 return true;
1679 }
1680 }
1681
1682 return VisitTagDecl(D);
1683}
1684
1685bool CursorVisitor::VisitAttributes(Decl *D) {
1686 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1687 i != e; ++i)
1688 if (Visit(MakeCXCursor(*i, D, TU)))
1689 return true;
1690
1691 return false;
1692}
1693
1694//===----------------------------------------------------------------------===//
1695// Data-recursive visitor methods.
1696//===----------------------------------------------------------------------===//
1697
1698namespace {
1699#define DEF_JOB(NAME, DATA, KIND)\
1700class NAME : public VisitorJob {\
1701public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001702 NAME(const DATA *d, CXCursor parent) : \
1703 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001704 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001705 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001706};
1707
1708DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1709DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1710DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1711DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1712DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1713 ExplicitTemplateArgsVisitKind)
1714DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1715DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1716DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1717#undef DEF_JOB
1718
1719class DeclVisit : public VisitorJob {
1720public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001721 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001722 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001723 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001724 static bool classof(const VisitorJob *VJ) {
1725 return VJ->getKind() == DeclVisitKind;
1726 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001727 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001728 bool isFirst() const { return data[1] ? true : false; }
1729};
1730class TypeLocVisit : public VisitorJob {
1731public:
1732 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1733 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1734 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1735
1736 static bool classof(const VisitorJob *VJ) {
1737 return VJ->getKind() == TypeLocVisitKind;
1738 }
1739
1740 TypeLoc get() const {
1741 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001742 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001743 }
1744};
1745
1746class LabelRefVisit : public VisitorJob {
1747public:
1748 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1749 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1750 labelLoc.getPtrEncoding()) {}
1751
1752 static bool classof(const VisitorJob *VJ) {
1753 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1754 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001755 const LabelDecl *get() const {
1756 return static_cast<const LabelDecl *>(data[0]);
1757 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001758 SourceLocation getLoc() const {
1759 return SourceLocation::getFromPtrEncoding(data[1]); }
1760};
1761
1762class NestedNameSpecifierLocVisit : public VisitorJob {
1763public:
1764 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1765 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1766 Qualifier.getNestedNameSpecifier(),
1767 Qualifier.getOpaqueData()) { }
1768
1769 static bool classof(const VisitorJob *VJ) {
1770 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1771 }
1772
1773 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001774 return NestedNameSpecifierLoc(
1775 const_cast<NestedNameSpecifier *>(
1776 static_cast<const NestedNameSpecifier *>(data[0])),
1777 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001778 }
1779};
1780
1781class DeclarationNameInfoVisit : public VisitorJob {
1782public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001783 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001784 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001785 static bool classof(const VisitorJob *VJ) {
1786 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1787 }
1788 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001789 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001790 switch (S->getStmtClass()) {
1791 default:
1792 llvm_unreachable("Unhandled Stmt");
1793 case clang::Stmt::MSDependentExistsStmtClass:
1794 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1795 case Stmt::CXXDependentScopeMemberExprClass:
1796 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1797 case Stmt::DependentScopeDeclRefExprClass:
1798 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1799 }
1800 }
1801};
1802class MemberRefVisit : public VisitorJob {
1803public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001804 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001805 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1806 L.getPtrEncoding()) {}
1807 static bool classof(const VisitorJob *VJ) {
1808 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1809 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001810 const FieldDecl *get() const {
1811 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001812 }
1813 SourceLocation getLoc() const {
1814 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1815 }
1816};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001817class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001818 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001819 VisitorWorkList &WL;
1820 CXCursor Parent;
1821public:
1822 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1823 : WL(wl), Parent(parent) {}
1824
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001825 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1826 void VisitBlockExpr(const BlockExpr *B);
1827 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1828 void VisitCompoundStmt(const CompoundStmt *S);
1829 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1830 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1831 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1832 void VisitCXXNewExpr(const CXXNewExpr *E);
1833 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1834 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1835 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1836 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1837 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1838 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1839 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1840 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1841 void VisitDeclRefExpr(const DeclRefExpr *D);
1842 void VisitDeclStmt(const DeclStmt *S);
1843 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1844 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1845 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1846 void VisitForStmt(const ForStmt *FS);
1847 void VisitGotoStmt(const GotoStmt *GS);
1848 void VisitIfStmt(const IfStmt *If);
1849 void VisitInitListExpr(const InitListExpr *IE);
1850 void VisitMemberExpr(const MemberExpr *M);
1851 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1852 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1853 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1854 void VisitOverloadExpr(const OverloadExpr *E);
1855 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1856 void VisitStmt(const Stmt *S);
1857 void VisitSwitchStmt(const SwitchStmt *S);
1858 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001859 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1860 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1861 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1862 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1863 void VisitVAArgExpr(const VAArgExpr *E);
1864 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1865 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1866 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1867 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001868 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1869 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001870
Guy Benyei11169dd2012-12-18 14:30:41 +00001871private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001872 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001873 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1874 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001875 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1876 void AddStmt(const Stmt *S);
1877 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001878 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001879 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001880 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001881};
1882} // end anonyous namespace
1883
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001884void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001885 // 'S' should always be non-null, since it comes from the
1886 // statement we are visiting.
1887 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1888}
1889
1890void
1891EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1892 if (Qualifier)
1893 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1894}
1895
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001896void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001897 if (S)
1898 WL.push_back(StmtVisit(S, Parent));
1899}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001900void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001901 if (D)
1902 WL.push_back(DeclVisit(D, Parent, isFirst));
1903}
1904void EnqueueVisitor::
1905 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1906 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001907 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001908}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001909void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001910 if (D)
1911 WL.push_back(MemberRefVisit(D, L, Parent));
1912}
1913void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1914 if (TI)
1915 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1916 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001917void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001918 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001919 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001920 AddStmt(*Child);
1921 }
1922 if (size == WL.size())
1923 return;
1924 // Now reverse the entries we just added. This will match the DFS
1925 // ordering performed by the worklist.
1926 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1927 std::reverse(I, E);
1928}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001929namespace {
1930class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1931 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001932 /// \brief Process clauses with list of variables.
1933 template <typename T>
1934 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001935public:
1936 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1937#define OPENMP_CLAUSE(Name, Class) \
1938 void Visit##Class(const Class *C);
1939#include "clang/Basic/OpenMPKinds.def"
1940};
1941
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001942void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1943 Visitor->AddStmt(C->getCondition());
1944}
1945
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001946void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001947
1948template<typename T>
1949void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
1950 for (typename T::varlist_const_iterator I = Node->varlist_begin(),
1951 E = Node->varlist_end();
1952 I != E; ++I)
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001953 Visitor->AddStmt(*I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001954}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001955
1956void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001957 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001958}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001959void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1960 const OMPFirstprivateClause *C) {
1961 VisitOMPClauseList(C);
1962}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001963void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001964 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001965}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001966}
Alexey Bataev756c1962013-09-24 03:17:45 +00001967
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001968void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1969 unsigned size = WL.size();
1970 OMPClauseEnqueue Visitor(this);
1971 Visitor.Visit(S);
1972 if (size == WL.size())
1973 return;
1974 // Now reverse the entries we just added. This will match the DFS
1975 // ordering performed by the worklist.
1976 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1977 std::reverse(I, E);
1978}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001979void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001980 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1981}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001982void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001983 AddDecl(B->getBlockDecl());
1984}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001985void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001986 EnqueueChildren(E);
1987 AddTypeLoc(E->getTypeSourceInfo());
1988}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001989void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1990 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001991 E = S->body_rend(); I != E; ++I) {
1992 AddStmt(*I);
1993 }
1994}
1995void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001996VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001997 AddStmt(S->getSubStmt());
1998 AddDeclarationNameInfo(S);
1999 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2000 AddNestedNameSpecifierLoc(QualifierLoc);
2001}
2002
2003void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002004VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002005 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2006 AddDeclarationNameInfo(E);
2007 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2008 AddNestedNameSpecifierLoc(QualifierLoc);
2009 if (!E->isImplicitAccess())
2010 AddStmt(E->getBase());
2011}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002012void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002013 // Enqueue the initializer , if any.
2014 AddStmt(E->getInitializer());
2015 // Enqueue the array size, if any.
2016 AddStmt(E->getArraySize());
2017 // Enqueue the allocated type.
2018 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2019 // Enqueue the placement arguments.
2020 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2021 AddStmt(E->getPlacementArg(I-1));
2022}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002023void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002024 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2025 AddStmt(CE->getArg(I-1));
2026 AddStmt(CE->getCallee());
2027 AddStmt(CE->getArg(0));
2028}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002029void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2030 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002031 // Visit the name of the type being destroyed.
2032 AddTypeLoc(E->getDestroyedTypeInfo());
2033 // Visit the scope type that looks disturbingly like the nested-name-specifier
2034 // but isn't.
2035 AddTypeLoc(E->getScopeTypeInfo());
2036 // Visit the nested-name-specifier.
2037 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2038 AddNestedNameSpecifierLoc(QualifierLoc);
2039 // Visit base expression.
2040 AddStmt(E->getBase());
2041}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002042void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2043 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002044 AddTypeLoc(E->getTypeSourceInfo());
2045}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002046void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2047 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002048 EnqueueChildren(E);
2049 AddTypeLoc(E->getTypeSourceInfo());
2050}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002051void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002052 EnqueueChildren(E);
2053 if (E->isTypeOperand())
2054 AddTypeLoc(E->getTypeOperandSourceInfo());
2055}
2056
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002057void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2058 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002059 EnqueueChildren(E);
2060 AddTypeLoc(E->getTypeSourceInfo());
2061}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002062void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002063 EnqueueChildren(E);
2064 if (E->isTypeOperand())
2065 AddTypeLoc(E->getTypeOperandSourceInfo());
2066}
2067
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002068void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002069 EnqueueChildren(S);
2070 AddDecl(S->getExceptionDecl());
2071}
2072
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002073void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002074 if (DR->hasExplicitTemplateArgs()) {
2075 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2076 }
2077 WL.push_back(DeclRefExprParts(DR, Parent));
2078}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002079void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2080 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002081 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2082 AddDeclarationNameInfo(E);
2083 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2084}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002085void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002086 unsigned size = WL.size();
2087 bool isFirst = true;
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002088 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00002089 D != DEnd; ++D) {
2090 AddDecl(*D, isFirst);
2091 isFirst = false;
2092 }
2093 if (size == WL.size())
2094 return;
2095 // Now reverse the entries we just added. This will match the DFS
2096 // ordering performed by the worklist.
2097 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2098 std::reverse(I, E);
2099}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002100void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002101 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002102 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002103 D = E->designators_rbegin(), DEnd = E->designators_rend();
2104 D != DEnd; ++D) {
2105 if (D->isFieldDesignator()) {
2106 if (FieldDecl *Field = D->getField())
2107 AddMemberRef(Field, D->getFieldLoc());
2108 continue;
2109 }
2110 if (D->isArrayDesignator()) {
2111 AddStmt(E->getArrayIndex(*D));
2112 continue;
2113 }
2114 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2115 AddStmt(E->getArrayRangeEnd(*D));
2116 AddStmt(E->getArrayRangeStart(*D));
2117 }
2118}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002119void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002120 EnqueueChildren(E);
2121 AddTypeLoc(E->getTypeInfoAsWritten());
2122}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002123void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002124 AddStmt(FS->getBody());
2125 AddStmt(FS->getInc());
2126 AddStmt(FS->getCond());
2127 AddDecl(FS->getConditionVariable());
2128 AddStmt(FS->getInit());
2129}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002130void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002131 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2132}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002133void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002134 AddStmt(If->getElse());
2135 AddStmt(If->getThen());
2136 AddStmt(If->getCond());
2137 AddDecl(If->getConditionVariable());
2138}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002139void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002140 // We care about the syntactic form of the initializer list, only.
2141 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2142 IE = Syntactic;
2143 EnqueueChildren(IE);
2144}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002145void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002146 WL.push_back(MemberExprParts(M, Parent));
2147
2148 // If the base of the member access expression is an implicit 'this', don't
2149 // visit it.
2150 // FIXME: If we ever want to show these implicit accesses, this will be
2151 // unfortunate. However, clang_getCursor() relies on this behavior.
2152 if (!M->isImplicitAccess())
2153 AddStmt(M->getBase());
2154}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002155void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002156 AddTypeLoc(E->getEncodedTypeSourceInfo());
2157}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002158void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002159 EnqueueChildren(M);
2160 AddTypeLoc(M->getClassReceiverTypeInfo());
2161}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002162void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002163 // Visit the components of the offsetof expression.
2164 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2165 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2166 const OffsetOfNode &Node = E->getComponent(I-1);
2167 switch (Node.getKind()) {
2168 case OffsetOfNode::Array:
2169 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2170 break;
2171 case OffsetOfNode::Field:
2172 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2173 break;
2174 case OffsetOfNode::Identifier:
2175 case OffsetOfNode::Base:
2176 continue;
2177 }
2178 }
2179 // Visit the type into which we're computing the offset.
2180 AddTypeLoc(E->getTypeSourceInfo());
2181}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002182void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002183 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2184 WL.push_back(OverloadExprParts(E, Parent));
2185}
2186void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002187 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002188 EnqueueChildren(E);
2189 if (E->isArgumentType())
2190 AddTypeLoc(E->getArgumentTypeInfo());
2191}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002192void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002193 EnqueueChildren(S);
2194}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002195void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002196 AddStmt(S->getBody());
2197 AddStmt(S->getCond());
2198 AddDecl(S->getConditionVariable());
2199}
2200
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002201void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002202 AddStmt(W->getBody());
2203 AddStmt(W->getCond());
2204 AddDecl(W->getConditionVariable());
2205}
2206
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002207void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002208 for (unsigned I = E->getNumArgs(); I > 0; --I)
2209 AddTypeLoc(E->getArg(I-1));
2210}
2211
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002212void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002213 AddTypeLoc(E->getQueriedTypeSourceInfo());
2214}
2215
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002216void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002217 EnqueueChildren(E);
2218}
2219
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002220void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002221 VisitOverloadExpr(U);
2222 if (!U->isImplicitAccess())
2223 AddStmt(U->getBase());
2224}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002225void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002226 AddStmt(E->getSubExpr());
2227 AddTypeLoc(E->getWrittenTypeInfo());
2228}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002229void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002230 WL.push_back(SizeOfPackExprParts(E, Parent));
2231}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002232void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002233 // If the opaque value has a source expression, just transparently
2234 // visit that. This is useful for (e.g.) pseudo-object expressions.
2235 if (Expr *SourceExpr = E->getSourceExpr())
2236 return Visit(SourceExpr);
2237}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002238void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002239 AddStmt(E->getBody());
2240 WL.push_back(LambdaExprParts(E, Parent));
2241}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002242void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002243 // Treat the expression like its syntactic form.
2244 Visit(E->getSyntacticForm());
2245}
2246
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002247void EnqueueVisitor::VisitOMPExecutableDirective(
2248 const OMPExecutableDirective *D) {
2249 EnqueueChildren(D);
2250 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2251 E = D->clauses().end();
2252 I != E; ++I)
2253 EnqueueChildren(*I);
2254}
2255
2256void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2257 VisitOMPExecutableDirective(D);
2258}
2259
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002260void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002261 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2262}
2263
2264bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2265 if (RegionOfInterest.isValid()) {
2266 SourceRange Range = getRawCursorExtent(C);
2267 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2268 return false;
2269 }
2270 return true;
2271}
2272
2273bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2274 while (!WL.empty()) {
2275 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002276 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002277
2278 // Set the Parent field, then back to its old value once we're done.
2279 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2280
2281 switch (LI.getKind()) {
2282 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002283 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002284 if (!D)
2285 continue;
2286
2287 // For now, perform default visitation for Decls.
2288 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2289 cast<DeclVisit>(&LI)->isFirst())))
2290 return true;
2291
2292 continue;
2293 }
2294 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2295 const ASTTemplateArgumentListInfo *ArgList =
2296 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2297 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2298 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2299 Arg != ArgEnd; ++Arg) {
2300 if (VisitTemplateArgumentLoc(*Arg))
2301 return true;
2302 }
2303 continue;
2304 }
2305 case VisitorJob::TypeLocVisitKind: {
2306 // Perform default visitation for TypeLocs.
2307 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2308 return true;
2309 continue;
2310 }
2311 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002312 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002313 if (LabelStmt *stmt = LS->getStmt()) {
2314 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2315 TU))) {
2316 return true;
2317 }
2318 }
2319 continue;
2320 }
2321
2322 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2323 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2324 if (VisitNestedNameSpecifierLoc(V->get()))
2325 return true;
2326 continue;
2327 }
2328
2329 case VisitorJob::DeclarationNameInfoVisitKind: {
2330 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2331 ->get()))
2332 return true;
2333 continue;
2334 }
2335 case VisitorJob::MemberRefVisitKind: {
2336 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2337 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2338 return true;
2339 continue;
2340 }
2341 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002342 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002343 if (!S)
2344 continue;
2345
2346 // Update the current cursor.
2347 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2348 if (!IsInRegionOfInterest(Cursor))
2349 continue;
2350 switch (Visitor(Cursor, Parent, ClientData)) {
2351 case CXChildVisit_Break: return true;
2352 case CXChildVisit_Continue: break;
2353 case CXChildVisit_Recurse:
2354 if (PostChildrenVisitor)
2355 WL.push_back(PostChildrenVisit(0, Cursor));
2356 EnqueueWorkList(WL, S);
2357 break;
2358 }
2359 continue;
2360 }
2361 case VisitorJob::MemberExprPartsKind: {
2362 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002363 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002364
2365 // Visit the nested-name-specifier
2366 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2367 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2368 return true;
2369
2370 // Visit the declaration name.
2371 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2372 return true;
2373
2374 // Visit the explicitly-specified template arguments, if any.
2375 if (M->hasExplicitTemplateArgs()) {
2376 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2377 *ArgEnd = Arg + M->getNumTemplateArgs();
2378 Arg != ArgEnd; ++Arg) {
2379 if (VisitTemplateArgumentLoc(*Arg))
2380 return true;
2381 }
2382 }
2383 continue;
2384 }
2385 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002386 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002387 // Visit nested-name-specifier, if present.
2388 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2389 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2390 return true;
2391 // Visit declaration name.
2392 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2393 return true;
2394 continue;
2395 }
2396 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002397 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002398 // Visit the nested-name-specifier.
2399 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2400 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2401 return true;
2402 // Visit the declaration name.
2403 if (VisitDeclarationNameInfo(O->getNameInfo()))
2404 return true;
2405 // Visit the overloaded declaration reference.
2406 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2407 return true;
2408 continue;
2409 }
2410 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002411 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002412 NamedDecl *Pack = E->getPack();
2413 if (isa<TemplateTypeParmDecl>(Pack)) {
2414 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2415 E->getPackLoc(), TU)))
2416 return true;
2417
2418 continue;
2419 }
2420
2421 if (isa<TemplateTemplateParmDecl>(Pack)) {
2422 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2423 E->getPackLoc(), TU)))
2424 return true;
2425
2426 continue;
2427 }
2428
2429 // Non-type template parameter packs and function parameter packs are
2430 // treated like DeclRefExpr cursors.
2431 continue;
2432 }
2433
2434 case VisitorJob::LambdaExprPartsKind: {
2435 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002436 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002437 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2438 CEnd = E->explicit_capture_end();
2439 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002440 // FIXME: Lambda init-captures.
2441 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002442 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002443
Guy Benyei11169dd2012-12-18 14:30:41 +00002444 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2445 C->getLocation(),
2446 TU)))
2447 return true;
2448 }
2449
2450 // Visit parameters and return type, if present.
2451 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2452 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2453 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2454 // Visit the whole type.
2455 if (Visit(TL))
2456 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002457 } else if (FunctionProtoTypeLoc Proto =
2458 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002459 if (E->hasExplicitParameters()) {
2460 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002461 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2462 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002463 return true;
2464 } else {
2465 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002466 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002467 return true;
2468 }
2469 }
2470 }
2471 break;
2472 }
2473
2474 case VisitorJob::PostChildrenVisitKind:
2475 if (PostChildrenVisitor(Parent, ClientData))
2476 return true;
2477 break;
2478 }
2479 }
2480 return false;
2481}
2482
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002483bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002484 VisitorWorkList *WL = 0;
2485 if (!WorkListFreeList.empty()) {
2486 WL = WorkListFreeList.back();
2487 WL->clear();
2488 WorkListFreeList.pop_back();
2489 }
2490 else {
2491 WL = new VisitorWorkList();
2492 WorkListCache.push_back(WL);
2493 }
2494 EnqueueWorkList(*WL, S);
2495 bool result = RunVisitorWorkList(*WL);
2496 WorkListFreeList.push_back(WL);
2497 return result;
2498}
2499
2500namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002501typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002502RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2503 const DeclarationNameInfo &NI,
2504 const SourceRange &QLoc,
2505 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2506 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2507 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2508 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2509
2510 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2511
2512 RefNamePieces Pieces;
2513
2514 if (WantQualifier && QLoc.isValid())
2515 Pieces.push_back(QLoc);
2516
2517 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2518 Pieces.push_back(NI.getLoc());
2519
2520 if (WantTemplateArgs && TemplateArgs)
2521 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2522 TemplateArgs->RAngleLoc));
2523
2524 if (Kind == DeclarationName::CXXOperatorName) {
2525 Pieces.push_back(SourceLocation::getFromRawEncoding(
2526 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2527 Pieces.push_back(SourceLocation::getFromRawEncoding(
2528 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2529 }
2530
2531 if (WantSinglePiece) {
2532 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2533 Pieces.clear();
2534 Pieces.push_back(R);
2535 }
2536
2537 return Pieces;
2538}
2539}
2540
2541//===----------------------------------------------------------------------===//
2542// Misc. API hooks.
2543//===----------------------------------------------------------------------===//
2544
2545static llvm::sys::Mutex EnableMultithreadingMutex;
2546static bool EnabledMultithreading;
2547
Chad Rosier05c71aa2013-03-27 18:28:23 +00002548static void fatal_error_handler(void *user_data, const std::string& reason,
2549 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002550 // Write the result out to stderr avoiding errs() because raw_ostreams can
2551 // call report_fatal_error.
2552 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2553 ::abort();
2554}
2555
2556extern "C" {
2557CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2558 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002559 // We use crash recovery to make some of our APIs more reliable, implicitly
2560 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002561 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2562 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002563
2564 // Enable support for multithreading in LLVM.
2565 {
2566 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2567 if (!EnabledMultithreading) {
2568 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2569 llvm::llvm_start_multithreaded();
2570 EnabledMultithreading = true;
2571 }
2572 }
2573
2574 CIndexer *CIdxr = new CIndexer();
2575 if (excludeDeclarationsFromPCH)
2576 CIdxr->setOnlyLocalDecls();
2577 if (displayDiagnostics)
2578 CIdxr->setDisplayDiagnostics();
2579
2580 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2581 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2582 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2583 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2584 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2585 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2586
2587 return CIdxr;
2588}
2589
2590void clang_disposeIndex(CXIndex CIdx) {
2591 if (CIdx)
2592 delete static_cast<CIndexer *>(CIdx);
2593}
2594
2595void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2596 if (CIdx)
2597 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2598}
2599
2600unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2601 if (CIdx)
2602 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2603 return 0;
2604}
2605
2606void clang_toggleCrashRecovery(unsigned isEnabled) {
2607 if (isEnabled)
2608 llvm::CrashRecoveryContext::Enable();
2609 else
2610 llvm::CrashRecoveryContext::Disable();
2611}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002612
Guy Benyei11169dd2012-12-18 14:30:41 +00002613CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2614 const char *ast_filename) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002615 CXTranslationUnit TU;
2616 enum CXErrorCode Result =
2617 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002618 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002619 assert((TU && Result == CXError_Success) ||
2620 (!TU && Result != CXError_Success));
2621 return TU;
2622}
2623
2624enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2625 const char *ast_filename,
2626 CXTranslationUnit *out_TU) {
2627 if (!CIdx || !ast_filename || !out_TU)
2628 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002629
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002630 LOG_FUNC_SECTION {
2631 *Log << ast_filename;
2632 }
2633
Guy Benyei11169dd2012-12-18 14:30:41 +00002634 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2635 FileSystemOptions FileSystemOpts;
2636
2637 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002638 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002639 CXXIdx->getOnlyLocalDecls(), None,
2640 /*CaptureDiagnostics=*/true,
2641 /*AllowPCHWithCompilerErrors=*/true,
2642 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002643 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2644 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002645}
2646
2647unsigned clang_defaultEditingTranslationUnitOptions() {
2648 return CXTranslationUnit_PrecompiledPreamble |
2649 CXTranslationUnit_CacheCompletionResults;
2650}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002651
Guy Benyei11169dd2012-12-18 14:30:41 +00002652CXTranslationUnit
2653clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2654 const char *source_filename,
2655 int num_command_line_args,
2656 const char * const *command_line_args,
2657 unsigned num_unsaved_files,
2658 struct CXUnsavedFile *unsaved_files) {
2659 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2660 return clang_parseTranslationUnit(CIdx, source_filename,
2661 command_line_args, num_command_line_args,
2662 unsaved_files, num_unsaved_files,
2663 Options);
2664}
2665
2666struct ParseTranslationUnitInfo {
2667 CXIndex CIdx;
2668 const char *source_filename;
2669 const char *const *command_line_args;
2670 int num_command_line_args;
2671 struct CXUnsavedFile *unsaved_files;
2672 unsigned num_unsaved_files;
2673 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002674 CXTranslationUnit *out_TU;
2675 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002676};
2677static void clang_parseTranslationUnit_Impl(void *UserData) {
2678 ParseTranslationUnitInfo *PTUI =
2679 static_cast<ParseTranslationUnitInfo*>(UserData);
2680 CXIndex CIdx = PTUI->CIdx;
2681 const char *source_filename = PTUI->source_filename;
2682 const char * const *command_line_args = PTUI->command_line_args;
2683 int num_command_line_args = PTUI->num_command_line_args;
2684 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2685 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2686 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002687 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002688
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002689 // Check arguments.
2690 if (!CIdx || !out_TU ||
2691 (unsaved_files == NULL && num_unsaved_files != 0)) {
2692 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002693 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002694 }
2695
2696 // Set up the initial return values.
2697 *out_TU = NULL;
2698 PTUI->result = CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002699
2700 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2701
2702 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2703 setThreadBackgroundPriority();
2704
2705 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2706 // FIXME: Add a flag for modules.
2707 TranslationUnitKind TUKind
2708 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002709 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002710 = options & CXTranslationUnit_CacheCompletionResults;
2711 bool IncludeBriefCommentsInCodeCompletion
2712 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2713 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2714 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2715
2716 // Configure the diagnostics.
2717 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002718 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002719
2720 // Recover resources if we crash before exiting this function.
2721 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2722 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2723 DiagCleanup(Diags.getPtr());
2724
2725 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2726 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2727
2728 // Recover resources if we crash before exiting this function.
2729 llvm::CrashRecoveryContextCleanupRegistrar<
2730 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2731
2732 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2733 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2734 const llvm::MemoryBuffer *Buffer
2735 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2736 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2737 Buffer));
2738 }
2739
2740 OwningPtr<std::vector<const char *> >
2741 Args(new std::vector<const char*>());
2742
2743 // Recover resources if we crash before exiting this method.
2744 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2745 ArgsCleanup(Args.get());
2746
2747 // Since the Clang C library is primarily used by batch tools dealing with
2748 // (often very broken) source code, where spell-checking can have a
2749 // significant negative impact on performance (particularly when
2750 // precompiled headers are involved), we disable it by default.
2751 // Only do this if we haven't found a spell-checking-related argument.
2752 bool FoundSpellCheckingArgument = false;
2753 for (int I = 0; I != num_command_line_args; ++I) {
2754 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2755 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2756 FoundSpellCheckingArgument = true;
2757 break;
2758 }
2759 }
2760 if (!FoundSpellCheckingArgument)
2761 Args->push_back("-fno-spell-checking");
2762
2763 Args->insert(Args->end(), command_line_args,
2764 command_line_args + num_command_line_args);
2765
2766 // The 'source_filename' argument is optional. If the caller does not
2767 // specify it then it is assumed that the source file is specified
2768 // in the actual argument list.
2769 // Put the source file after command_line_args otherwise if '-x' flag is
2770 // present it will be unused.
2771 if (source_filename)
2772 Args->push_back(source_filename);
2773
2774 // Do we need the detailed preprocessing record?
2775 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2776 Args->push_back("-Xclang");
2777 Args->push_back("-detailed-preprocessing-record");
2778 }
2779
2780 unsigned NumErrors = Diags->getClient()->getNumErrors();
2781 OwningPtr<ASTUnit> ErrUnit;
2782 OwningPtr<ASTUnit> Unit(
2783 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2784 /* vector::data() not portable */,
2785 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2786 Diags,
2787 CXXIdx->getClangResourcesPath(),
2788 CXXIdx->getOnlyLocalDecls(),
2789 /*CaptureDiagnostics=*/true,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002790 *RemappedFiles.get(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002791 /*RemappedFilesKeepOriginalName=*/true,
2792 PrecompilePreamble,
2793 TUKind,
Alp Toker8c8a8752013-12-03 06:53:35 +00002794 CacheCodeCompletionResults,
Guy Benyei11169dd2012-12-18 14:30:41 +00002795 IncludeBriefCommentsInCodeCompletion,
2796 /*AllowPCHWithCompilerErrors=*/true,
2797 SkipFunctionBodies,
2798 /*UserFilesAreVolatile=*/true,
2799 ForSerialization,
2800 &ErrUnit));
2801
2802 if (NumErrors != Diags->getClient()->getNumErrors()) {
2803 // Make sure to check that 'Unit' is non-NULL.
2804 if (CXXIdx->getDisplayDiagnostics())
2805 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2806 }
2807
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002808 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2809 PTUI->result = CXError_ASTReadError;
2810 } else {
2811 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.take());
2812 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2813 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002814}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002815
2816CXTranslationUnit
2817clang_parseTranslationUnit(CXIndex CIdx,
2818 const char *source_filename,
2819 const char *const *command_line_args,
2820 int num_command_line_args,
2821 struct CXUnsavedFile *unsaved_files,
2822 unsigned num_unsaved_files,
2823 unsigned options) {
2824 CXTranslationUnit TU;
2825 enum CXErrorCode Result = clang_parseTranslationUnit2(
2826 CIdx, source_filename, command_line_args, num_command_line_args,
2827 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002828 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002829 assert((TU && Result == CXError_Success) ||
2830 (!TU && Result != CXError_Success));
2831 return TU;
2832}
2833
2834enum CXErrorCode clang_parseTranslationUnit2(
2835 CXIndex CIdx,
2836 const char *source_filename,
2837 const char *const *command_line_args,
2838 int num_command_line_args,
2839 struct CXUnsavedFile *unsaved_files,
2840 unsigned num_unsaved_files,
2841 unsigned options,
2842 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002843 LOG_FUNC_SECTION {
2844 *Log << source_filename << ": ";
2845 for (int i = 0; i != num_command_line_args; ++i)
2846 *Log << command_line_args[i] << " ";
2847 }
2848
Guy Benyei11169dd2012-12-18 14:30:41 +00002849 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2850 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002851 num_unsaved_files, options, out_TU,
2852 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002853 llvm::CrashRecoveryContext CRC;
2854
2855 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2856 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2857 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2858 fprintf(stderr, " 'command_line_args' : [");
2859 for (int i = 0; i != num_command_line_args; ++i) {
2860 if (i)
2861 fprintf(stderr, ", ");
2862 fprintf(stderr, "'%s'", command_line_args[i]);
2863 }
2864 fprintf(stderr, "],\n");
2865 fprintf(stderr, " 'unsaved_files' : [");
2866 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2867 if (i)
2868 fprintf(stderr, ", ");
2869 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2870 unsaved_files[i].Length);
2871 }
2872 fprintf(stderr, "],\n");
2873 fprintf(stderr, " 'options' : %d,\n", options);
2874 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002875
2876 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002877 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002878 if (CXTranslationUnit *TU = PTUI.out_TU)
2879 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002880 }
2881
2882 return PTUI.result;
2883}
2884
2885unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2886 return CXSaveTranslationUnit_None;
2887}
2888
2889namespace {
2890
2891struct SaveTranslationUnitInfo {
2892 CXTranslationUnit TU;
2893 const char *FileName;
2894 unsigned options;
2895 CXSaveError result;
2896};
2897
2898}
2899
2900static void clang_saveTranslationUnit_Impl(void *UserData) {
2901 SaveTranslationUnitInfo *STUI =
2902 static_cast<SaveTranslationUnitInfo*>(UserData);
2903
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002904 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002905 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2906 setThreadBackgroundPriority();
2907
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002908 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002909 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2910}
2911
2912int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2913 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002914 LOG_FUNC_SECTION {
2915 *Log << TU << ' ' << FileName;
2916 }
2917
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002918 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002919 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002920 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002921 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002922
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002923 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002924 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2925 if (!CXXUnit->hasSema())
2926 return CXSaveError_InvalidTU;
2927
2928 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2929
2930 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2931 getenv("LIBCLANG_NOTHREADS")) {
2932 clang_saveTranslationUnit_Impl(&STUI);
2933
2934 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2935 PrintLibclangResourceUsage(TU);
2936
2937 return STUI.result;
2938 }
2939
2940 // We have an AST that has invalid nodes due to compiler errors.
2941 // Use a crash recovery thread for protection.
2942
2943 llvm::CrashRecoveryContext CRC;
2944
2945 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2946 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2947 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2948 fprintf(stderr, " 'options' : %d,\n", options);
2949 fprintf(stderr, "}\n");
2950
2951 return CXSaveError_Unknown;
2952
2953 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2954 PrintLibclangResourceUsage(TU);
2955 }
2956
2957 return STUI.result;
2958}
2959
2960void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2961 if (CTUnit) {
2962 // If the translation unit has been marked as unsafe to free, just discard
2963 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002964 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2965 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002966 return;
2967
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002968 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002969 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002970 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2971 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002972 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002973 delete CTUnit;
2974 }
2975}
2976
2977unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2978 return CXReparse_None;
2979}
2980
2981struct ReparseTranslationUnitInfo {
2982 CXTranslationUnit TU;
2983 unsigned num_unsaved_files;
2984 struct CXUnsavedFile *unsaved_files;
2985 unsigned options;
2986 int result;
2987};
2988
2989static void clang_reparseTranslationUnit_Impl(void *UserData) {
2990 ReparseTranslationUnitInfo *RTUI =
2991 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002992 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002993
Guy Benyei11169dd2012-12-18 14:30:41 +00002994 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002995 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2996 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2997 unsigned options = RTUI->options;
2998 (void) options;
2999
3000 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003001 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003002 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003003 RTUI->result = CXError_InvalidArguments;
3004 return;
3005 }
3006 if (unsaved_files == NULL && num_unsaved_files != 0) {
3007 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003008 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003009 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003010
3011 // Reset the associated diagnostics.
3012 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3013 TU->Diagnostics = 0;
3014
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003015 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003016 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3017 setThreadBackgroundPriority();
3018
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003019 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003020 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3021
3022 OwningPtr<std::vector<ASTUnit::RemappedFile> >
3023 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
3024
3025 // Recover resources if we crash before exiting this function.
3026 llvm::CrashRecoveryContextCleanupRegistrar<
3027 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3028
3029 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3030 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3031 const llvm::MemoryBuffer *Buffer
3032 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3033 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3034 Buffer));
3035 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003036
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003037 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003038 RTUI->result = CXError_Success;
3039 else if (isASTReadError(CXXUnit))
3040 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003041}
3042
3043int clang_reparseTranslationUnit(CXTranslationUnit TU,
3044 unsigned num_unsaved_files,
3045 struct CXUnsavedFile *unsaved_files,
3046 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003047 LOG_FUNC_SECTION {
3048 *Log << TU;
3049 }
3050
Guy Benyei11169dd2012-12-18 14:30:41 +00003051 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003052 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003053
3054 if (getenv("LIBCLANG_NOTHREADS")) {
3055 clang_reparseTranslationUnit_Impl(&RTUI);
3056 return RTUI.result;
3057 }
3058
3059 llvm::CrashRecoveryContext CRC;
3060
3061 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3062 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003063 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003064 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003065 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3066 PrintLibclangResourceUsage(TU);
3067
3068 return RTUI.result;
3069}
3070
3071
3072CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003073 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003074 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003075 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003076 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003077
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003078 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003079 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003080}
3081
3082CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003083 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003084 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003085 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003086 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003087
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003088 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003089 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3090}
3091
3092} // end: extern "C"
3093
3094//===----------------------------------------------------------------------===//
3095// CXFile Operations.
3096//===----------------------------------------------------------------------===//
3097
3098extern "C" {
3099CXString clang_getFileName(CXFile SFile) {
3100 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003101 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003102
3103 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003104 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003105}
3106
3107time_t clang_getFileTime(CXFile SFile) {
3108 if (!SFile)
3109 return 0;
3110
3111 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3112 return FEnt->getModificationTime();
3113}
3114
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003115CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003116 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003117 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003118 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003119 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003120
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003121 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003122
3123 FileManager &FMgr = CXXUnit->getFileManager();
3124 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3125}
3126
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003127unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3128 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003129 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003130 LOG_BAD_TU(TU);
3131 return 0;
3132 }
3133
3134 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003135 return 0;
3136
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003137 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003138 FileEntry *FEnt = static_cast<FileEntry *>(file);
3139 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3140 .isFileMultipleIncludeGuarded(FEnt);
3141}
3142
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003143int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3144 if (!file || !outID)
3145 return 1;
3146
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003147 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003148 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3149 outID->data[0] = ID.getDevice();
3150 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003151 outID->data[2] = FEnt->getModificationTime();
3152 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003153}
3154
Guy Benyei11169dd2012-12-18 14:30:41 +00003155} // end: extern "C"
3156
3157//===----------------------------------------------------------------------===//
3158// CXCursor Operations.
3159//===----------------------------------------------------------------------===//
3160
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003161static const Decl *getDeclFromExpr(const Stmt *E) {
3162 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003163 return getDeclFromExpr(CE->getSubExpr());
3164
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003165 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003166 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003167 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003168 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003169 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003170 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003171 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003172 if (PRE->isExplicitProperty())
3173 return PRE->getExplicitProperty();
3174 // It could be messaging both getter and setter as in:
3175 // ++myobj.myprop;
3176 // in which case prefer to associate the setter since it is less obvious
3177 // from inspecting the source that the setter is going to get called.
3178 if (PRE->isMessagingSetter())
3179 return PRE->getImplicitPropertySetter();
3180 return PRE->getImplicitPropertyGetter();
3181 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003182 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003183 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003184 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003185 if (Expr *Src = OVE->getSourceExpr())
3186 return getDeclFromExpr(Src);
3187
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003188 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003189 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003190 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003191 if (!CE->isElidable())
3192 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003193 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003194 return OME->getMethodDecl();
3195
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003196 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003197 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003198 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003199 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3200 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003201 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003202 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3203 isa<ParmVarDecl>(SizeOfPack->getPack()))
3204 return SizeOfPack->getPack();
3205
3206 return 0;
3207}
3208
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003209static SourceLocation getLocationFromExpr(const Expr *E) {
3210 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003211 return getLocationFromExpr(CE->getSubExpr());
3212
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003213 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003214 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003215 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003216 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003217 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003218 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003219 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003220 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003221 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003222 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003223 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003224 return PropRef->getLocation();
3225
3226 return E->getLocStart();
3227}
3228
3229extern "C" {
3230
3231unsigned clang_visitChildren(CXCursor parent,
3232 CXCursorVisitor visitor,
3233 CXClientData client_data) {
3234 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3235 /*VisitPreprocessorLast=*/false);
3236 return CursorVis.VisitChildren(parent);
3237}
3238
3239#ifndef __has_feature
3240#define __has_feature(x) 0
3241#endif
3242#if __has_feature(blocks)
3243typedef enum CXChildVisitResult
3244 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3245
3246static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3247 CXClientData client_data) {
3248 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3249 return block(cursor, parent);
3250}
3251#else
3252// If we are compiled with a compiler that doesn't have native blocks support,
3253// define and call the block manually, so the
3254typedef struct _CXChildVisitResult
3255{
3256 void *isa;
3257 int flags;
3258 int reserved;
3259 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3260 CXCursor);
3261} *CXCursorVisitorBlock;
3262
3263static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3264 CXClientData client_data) {
3265 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3266 return block->invoke(block, cursor, parent);
3267}
3268#endif
3269
3270
3271unsigned clang_visitChildrenWithBlock(CXCursor parent,
3272 CXCursorVisitorBlock block) {
3273 return clang_visitChildren(parent, visitWithBlock, block);
3274}
3275
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003276static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003277 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003278 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003279
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003280 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003281 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003282 if (const ObjCPropertyImplDecl *PropImpl =
3283 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003284 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003285 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003286
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003287 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003288 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003289 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003290
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003291 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003292 }
3293
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003294 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003295 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003296
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003297 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003298 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3299 // and returns different names. NamedDecl returns the class name and
3300 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003301 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003302
3303 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003304 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003305
3306 SmallString<1024> S;
3307 llvm::raw_svector_ostream os(S);
3308 ND->printName(os);
3309
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003310 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003311}
3312
3313CXString clang_getCursorSpelling(CXCursor C) {
3314 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003315 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003316
3317 if (clang_isReference(C.kind)) {
3318 switch (C.kind) {
3319 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003320 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003321 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003322 }
3323 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003324 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003325 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003326 }
3327 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003328 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003329 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003330 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003331 }
3332 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003333 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003334 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003335 }
3336 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003337 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 assert(Type && "Missing type decl");
3339
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003340 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003341 getAsString());
3342 }
3343 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003344 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003345 assert(Template && "Missing template decl");
3346
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003347 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 }
3349
3350 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003351 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003352 assert(NS && "Missing namespace decl");
3353
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003354 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003355 }
3356
3357 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003358 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003359 assert(Field && "Missing member decl");
3360
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003361 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003362 }
3363
3364 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003365 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003366 assert(Label && "Missing label");
3367
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003368 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003369 }
3370
3371 case CXCursor_OverloadedDeclRef: {
3372 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003373 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3374 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003375 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003376 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003377 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003378 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003379 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 OverloadedTemplateStorage *Ovl
3381 = Storage.get<OverloadedTemplateStorage*>();
3382 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003383 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003384 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003385 }
3386
3387 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003388 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003389 assert(Var && "Missing variable decl");
3390
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003391 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003392 }
3393
3394 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003395 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003396 }
3397 }
3398
3399 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003400 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003401 if (D)
3402 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003403 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003404 }
3405
3406 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003407 const Stmt *S = getCursorStmt(C);
3408 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003409 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003410
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003411 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003412 }
3413
3414 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003415 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003416 ->getNameStart());
3417
3418 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003419 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003420 ->getNameStart());
3421
3422 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003423 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003424
3425 if (clang_isDeclaration(C.kind))
3426 return getDeclSpelling(getCursorDecl(C));
3427
3428 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003429 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003430 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003431 }
3432
3433 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003434 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003435 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003436 }
3437
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003438 if (C.kind == CXCursor_PackedAttr) {
3439 return cxstring::createRef("packed");
3440 }
3441
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003442 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003443}
3444
3445CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3446 unsigned pieceIndex,
3447 unsigned options) {
3448 if (clang_Cursor_isNull(C))
3449 return clang_getNullRange();
3450
3451 ASTContext &Ctx = getCursorContext(C);
3452
3453 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003454 const Stmt *S = getCursorStmt(C);
3455 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003456 if (pieceIndex > 0)
3457 return clang_getNullRange();
3458 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3459 }
3460
3461 return clang_getNullRange();
3462 }
3463
3464 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003465 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003466 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3467 if (pieceIndex >= ME->getNumSelectorLocs())
3468 return clang_getNullRange();
3469 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3470 }
3471 }
3472
3473 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3474 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003475 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003476 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3477 if (pieceIndex >= MD->getNumSelectorLocs())
3478 return clang_getNullRange();
3479 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3480 }
3481 }
3482
3483 if (C.kind == CXCursor_ObjCCategoryDecl ||
3484 C.kind == CXCursor_ObjCCategoryImplDecl) {
3485 if (pieceIndex > 0)
3486 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003487 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003488 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3489 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003490 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003491 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3492 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3493 }
3494
3495 if (C.kind == CXCursor_ModuleImportDecl) {
3496 if (pieceIndex > 0)
3497 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003498 if (const ImportDecl *ImportD =
3499 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003500 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3501 if (!Locs.empty())
3502 return cxloc::translateSourceRange(Ctx,
3503 SourceRange(Locs.front(), Locs.back()));
3504 }
3505 return clang_getNullRange();
3506 }
3507
3508 // FIXME: A CXCursor_InclusionDirective should give the location of the
3509 // filename, but we don't keep track of this.
3510
3511 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3512 // but we don't keep track of this.
3513
3514 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3515 // but we don't keep track of this.
3516
3517 // Default handling, give the location of the cursor.
3518
3519 if (pieceIndex > 0)
3520 return clang_getNullRange();
3521
3522 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3523 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3524 return cxloc::translateSourceRange(Ctx, Loc);
3525}
3526
3527CXString clang_getCursorDisplayName(CXCursor C) {
3528 if (!clang_isDeclaration(C.kind))
3529 return clang_getCursorSpelling(C);
3530
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003531 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003532 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003533 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003534
3535 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003536 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003537 D = FunTmpl->getTemplatedDecl();
3538
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003539 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003540 SmallString<64> Str;
3541 llvm::raw_svector_ostream OS(Str);
3542 OS << *Function;
3543 if (Function->getPrimaryTemplate())
3544 OS << "<>";
3545 OS << "(";
3546 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3547 if (I)
3548 OS << ", ";
3549 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3550 }
3551
3552 if (Function->isVariadic()) {
3553 if (Function->getNumParams())
3554 OS << ", ";
3555 OS << "...";
3556 }
3557 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003558 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003559 }
3560
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003561 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003562 SmallString<64> Str;
3563 llvm::raw_svector_ostream OS(Str);
3564 OS << *ClassTemplate;
3565 OS << "<";
3566 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3567 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3568 if (I)
3569 OS << ", ";
3570
3571 NamedDecl *Param = Params->getParam(I);
3572 if (Param->getIdentifier()) {
3573 OS << Param->getIdentifier()->getName();
3574 continue;
3575 }
3576
3577 // There is no parameter name, which makes this tricky. Try to come up
3578 // with something useful that isn't too long.
3579 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3580 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3581 else if (NonTypeTemplateParmDecl *NTTP
3582 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3583 OS << NTTP->getType().getAsString(Policy);
3584 else
3585 OS << "template<...> class";
3586 }
3587
3588 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003589 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003590 }
3591
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003592 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003593 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3594 // If the type was explicitly written, use that.
3595 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003596 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003597
Benjamin Kramer9170e912013-02-22 15:46:01 +00003598 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 llvm::raw_svector_ostream OS(Str);
3600 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003601 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003602 ClassSpec->getTemplateArgs().data(),
3603 ClassSpec->getTemplateArgs().size(),
3604 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003605 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003606 }
3607
3608 return clang_getCursorSpelling(C);
3609}
3610
3611CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3612 switch (Kind) {
3613 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003614 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003615 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003616 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003617 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003618 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003619 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003620 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003621 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003622 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003624 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003626 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003628 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003630 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003632 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003633 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003634 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003636 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003638 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003639 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003640 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003642 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003643 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003644 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003646 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003648 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003650 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003652 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003654 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003656 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003658 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003660 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003662 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003664 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003666 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003668 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003670 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003672 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003741 case CXCursor_ObjCSelfExpr:
3742 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003859 case CXCursor_PackedAttr:
3860 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003909 case CXCursor_OMPParallelDirective:
3910 return cxstring::createRef("OMPParallelDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 }
3912
3913 llvm_unreachable("Unhandled CXCursorKind");
3914}
3915
3916struct GetCursorData {
3917 SourceLocation TokenBeginLoc;
3918 bool PointsAtMacroArgExpansion;
3919 bool VisitedObjCPropertyImplDecl;
3920 SourceLocation VisitedDeclaratorDeclStartLoc;
3921 CXCursor &BestCursor;
3922
3923 GetCursorData(SourceManager &SM,
3924 SourceLocation tokenBegin, CXCursor &outputCursor)
3925 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3926 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3927 VisitedObjCPropertyImplDecl = false;
3928 }
3929};
3930
3931static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3932 CXCursor parent,
3933 CXClientData client_data) {
3934 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3935 CXCursor *BestCursor = &Data->BestCursor;
3936
3937 // If we point inside a macro argument we should provide info of what the
3938 // token is so use the actual cursor, don't replace it with a macro expansion
3939 // cursor.
3940 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3941 return CXChildVisit_Recurse;
3942
3943 if (clang_isDeclaration(cursor.kind)) {
3944 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003945 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3947 if (MD->isImplicit())
3948 return CXChildVisit_Break;
3949
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003950 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003951 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3952 // Check that when we have multiple @class references in the same line,
3953 // that later ones do not override the previous ones.
3954 // If we have:
3955 // @class Foo, Bar;
3956 // source ranges for both start at '@', so 'Bar' will end up overriding
3957 // 'Foo' even though the cursor location was at 'Foo'.
3958 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3959 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003960 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3962 if (PrevID != ID &&
3963 !PrevID->isThisDeclarationADefinition() &&
3964 !ID->isThisDeclarationADefinition())
3965 return CXChildVisit_Break;
3966 }
3967
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003968 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3970 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3971 // Check that when we have multiple declarators in the same line,
3972 // that later ones do not override the previous ones.
3973 // If we have:
3974 // int Foo, Bar;
3975 // source ranges for both start at 'int', so 'Bar' will end up overriding
3976 // 'Foo' even though the cursor location was at 'Foo'.
3977 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3978 return CXChildVisit_Break;
3979 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3980
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003981 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3983 (void)PropImp;
3984 // Check that when we have multiple @synthesize in the same line,
3985 // that later ones do not override the previous ones.
3986 // If we have:
3987 // @synthesize Foo, Bar;
3988 // source ranges for both start at '@', so 'Bar' will end up overriding
3989 // 'Foo' even though the cursor location was at 'Foo'.
3990 if (Data->VisitedObjCPropertyImplDecl)
3991 return CXChildVisit_Break;
3992 Data->VisitedObjCPropertyImplDecl = true;
3993 }
3994 }
3995
3996 if (clang_isExpression(cursor.kind) &&
3997 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003998 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 // Avoid having the cursor of an expression replace the declaration cursor
4000 // when the expression source range overlaps the declaration range.
4001 // This can happen for C++ constructor expressions whose range generally
4002 // include the variable declaration, e.g.:
4003 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4004 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4005 D->getLocation() == Data->TokenBeginLoc)
4006 return CXChildVisit_Break;
4007 }
4008 }
4009
4010 // If our current best cursor is the construction of a temporary object,
4011 // don't replace that cursor with a type reference, because we want
4012 // clang_getCursor() to point at the constructor.
4013 if (clang_isExpression(BestCursor->kind) &&
4014 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4015 cursor.kind == CXCursor_TypeRef) {
4016 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4017 // as having the actual point on the type reference.
4018 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4019 return CXChildVisit_Recurse;
4020 }
4021
4022 *BestCursor = cursor;
4023 return CXChildVisit_Recurse;
4024}
4025
4026CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004027 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004028 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004030 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004031
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004032 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4034
4035 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4036 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4037
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004038 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 CXFile SearchFile;
4040 unsigned SearchLine, SearchColumn;
4041 CXFile ResultFile;
4042 unsigned ResultLine, ResultColumn;
4043 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4044 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4045 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4046
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004047 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4048 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 &ResultColumn, 0);
4050 SearchFileName = clang_getFileName(SearchFile);
4051 ResultFileName = clang_getFileName(ResultFile);
4052 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4053 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004054 *Log << llvm::format("(%s:%d:%d) = %s",
4055 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4056 clang_getCString(KindSpelling))
4057 << llvm::format("(%s:%d:%d):%s%s",
4058 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4059 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 clang_disposeString(SearchFileName);
4061 clang_disposeString(ResultFileName);
4062 clang_disposeString(KindSpelling);
4063 clang_disposeString(USR);
4064
4065 CXCursor Definition = clang_getCursorDefinition(Result);
4066 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4067 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4068 CXString DefinitionKindSpelling
4069 = clang_getCursorKindSpelling(Definition.kind);
4070 CXFile DefinitionFile;
4071 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004072 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004073 &DefinitionLine, &DefinitionColumn, 0);
4074 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004075 *Log << llvm::format(" -> %s(%s:%d:%d)",
4076 clang_getCString(DefinitionKindSpelling),
4077 clang_getCString(DefinitionFileName),
4078 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 clang_disposeString(DefinitionFileName);
4080 clang_disposeString(DefinitionKindSpelling);
4081 }
4082 }
4083
4084 return Result;
4085}
4086
4087CXCursor clang_getNullCursor(void) {
4088 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4089}
4090
4091unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004092 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4093 // can't set consistently. For example, when visiting a DeclStmt we will set
4094 // it but we don't set it on the result of clang_getCursorDefinition for
4095 // a reference of the same declaration.
4096 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4097 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4098 // to provide that kind of info.
4099 if (clang_isDeclaration(X.kind))
4100 X.data[1] = 0;
4101 if (clang_isDeclaration(Y.kind))
4102 Y.data[1] = 0;
4103
Guy Benyei11169dd2012-12-18 14:30:41 +00004104 return X == Y;
4105}
4106
4107unsigned clang_hashCursor(CXCursor C) {
4108 unsigned Index = 0;
4109 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4110 Index = 1;
4111
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004112 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 std::make_pair(C.kind, C.data[Index]));
4114}
4115
4116unsigned clang_isInvalid(enum CXCursorKind K) {
4117 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4118}
4119
4120unsigned clang_isDeclaration(enum CXCursorKind K) {
4121 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4122 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4123}
4124
4125unsigned clang_isReference(enum CXCursorKind K) {
4126 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4127}
4128
4129unsigned clang_isExpression(enum CXCursorKind K) {
4130 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4131}
4132
4133unsigned clang_isStatement(enum CXCursorKind K) {
4134 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4135}
4136
4137unsigned clang_isAttribute(enum CXCursorKind K) {
4138 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4139}
4140
4141unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4142 return K == CXCursor_TranslationUnit;
4143}
4144
4145unsigned clang_isPreprocessing(enum CXCursorKind K) {
4146 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4147}
4148
4149unsigned clang_isUnexposed(enum CXCursorKind K) {
4150 switch (K) {
4151 case CXCursor_UnexposedDecl:
4152 case CXCursor_UnexposedExpr:
4153 case CXCursor_UnexposedStmt:
4154 case CXCursor_UnexposedAttr:
4155 return true;
4156 default:
4157 return false;
4158 }
4159}
4160
4161CXCursorKind clang_getCursorKind(CXCursor C) {
4162 return C.kind;
4163}
4164
4165CXSourceLocation clang_getCursorLocation(CXCursor C) {
4166 if (clang_isReference(C.kind)) {
4167 switch (C.kind) {
4168 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004169 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004170 = getCursorObjCSuperClassRef(C);
4171 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4172 }
4173
4174 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004175 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004176 = getCursorObjCProtocolRef(C);
4177 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4178 }
4179
4180 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004181 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004182 = getCursorObjCClassRef(C);
4183 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4184 }
4185
4186 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004187 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004188 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4189 }
4190
4191 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004192 std::pair<const TemplateDecl *, SourceLocation> P =
4193 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004194 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4195 }
4196
4197 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004198 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4200 }
4201
4202 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004203 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004204 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4205 }
4206
4207 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004208 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004209 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4210 }
4211
4212 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004213 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004214 if (!BaseSpec)
4215 return clang_getNullLocation();
4216
4217 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4218 return cxloc::translateSourceLocation(getCursorContext(C),
4219 TSInfo->getTypeLoc().getBeginLoc());
4220
4221 return cxloc::translateSourceLocation(getCursorContext(C),
4222 BaseSpec->getLocStart());
4223 }
4224
4225 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004226 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004227 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4228 }
4229
4230 case CXCursor_OverloadedDeclRef:
4231 return cxloc::translateSourceLocation(getCursorContext(C),
4232 getCursorOverloadedDeclRef(C).second);
4233
4234 default:
4235 // FIXME: Need a way to enumerate all non-reference cases.
4236 llvm_unreachable("Missed a reference kind");
4237 }
4238 }
4239
4240 if (clang_isExpression(C.kind))
4241 return cxloc::translateSourceLocation(getCursorContext(C),
4242 getLocationFromExpr(getCursorExpr(C)));
4243
4244 if (clang_isStatement(C.kind))
4245 return cxloc::translateSourceLocation(getCursorContext(C),
4246 getCursorStmt(C)->getLocStart());
4247
4248 if (C.kind == CXCursor_PreprocessingDirective) {
4249 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4250 return cxloc::translateSourceLocation(getCursorContext(C), L);
4251 }
4252
4253 if (C.kind == CXCursor_MacroExpansion) {
4254 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004255 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004256 return cxloc::translateSourceLocation(getCursorContext(C), L);
4257 }
4258
4259 if (C.kind == CXCursor_MacroDefinition) {
4260 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4261 return cxloc::translateSourceLocation(getCursorContext(C), L);
4262 }
4263
4264 if (C.kind == CXCursor_InclusionDirective) {
4265 SourceLocation L
4266 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4267 return cxloc::translateSourceLocation(getCursorContext(C), L);
4268 }
4269
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004270 if (clang_isAttribute(C.kind)) {
4271 SourceLocation L
4272 = cxcursor::getCursorAttr(C)->getLocation();
4273 return cxloc::translateSourceLocation(getCursorContext(C), L);
4274 }
4275
Guy Benyei11169dd2012-12-18 14:30:41 +00004276 if (!clang_isDeclaration(C.kind))
4277 return clang_getNullLocation();
4278
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004279 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004280 if (!D)
4281 return clang_getNullLocation();
4282
4283 SourceLocation Loc = D->getLocation();
4284 // FIXME: Multiple variables declared in a single declaration
4285 // currently lack the information needed to correctly determine their
4286 // ranges when accounting for the type-specifier. We use context
4287 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4288 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004289 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004290 if (!cxcursor::isFirstInDeclGroup(C))
4291 Loc = VD->getLocation();
4292 }
4293
4294 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004295 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004296 Loc = MD->getSelectorStartLoc();
4297
4298 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4299}
4300
4301} // end extern "C"
4302
4303CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4304 assert(TU);
4305
4306 // Guard against an invalid SourceLocation, or we may assert in one
4307 // of the following calls.
4308 if (SLoc.isInvalid())
4309 return clang_getNullCursor();
4310
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004311 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004312
4313 // Translate the given source location to make it point at the beginning of
4314 // the token under the cursor.
4315 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4316 CXXUnit->getASTContext().getLangOpts());
4317
4318 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4319 if (SLoc.isValid()) {
4320 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4321 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4322 /*VisitPreprocessorLast=*/true,
4323 /*VisitIncludedEntities=*/false,
4324 SourceLocation(SLoc));
4325 CursorVis.visitFileRegion();
4326 }
4327
4328 return Result;
4329}
4330
4331static SourceRange getRawCursorExtent(CXCursor C) {
4332 if (clang_isReference(C.kind)) {
4333 switch (C.kind) {
4334 case CXCursor_ObjCSuperClassRef:
4335 return getCursorObjCSuperClassRef(C).second;
4336
4337 case CXCursor_ObjCProtocolRef:
4338 return getCursorObjCProtocolRef(C).second;
4339
4340 case CXCursor_ObjCClassRef:
4341 return getCursorObjCClassRef(C).second;
4342
4343 case CXCursor_TypeRef:
4344 return getCursorTypeRef(C).second;
4345
4346 case CXCursor_TemplateRef:
4347 return getCursorTemplateRef(C).second;
4348
4349 case CXCursor_NamespaceRef:
4350 return getCursorNamespaceRef(C).second;
4351
4352 case CXCursor_MemberRef:
4353 return getCursorMemberRef(C).second;
4354
4355 case CXCursor_CXXBaseSpecifier:
4356 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4357
4358 case CXCursor_LabelRef:
4359 return getCursorLabelRef(C).second;
4360
4361 case CXCursor_OverloadedDeclRef:
4362 return getCursorOverloadedDeclRef(C).second;
4363
4364 case CXCursor_VariableRef:
4365 return getCursorVariableRef(C).second;
4366
4367 default:
4368 // FIXME: Need a way to enumerate all non-reference cases.
4369 llvm_unreachable("Missed a reference kind");
4370 }
4371 }
4372
4373 if (clang_isExpression(C.kind))
4374 return getCursorExpr(C)->getSourceRange();
4375
4376 if (clang_isStatement(C.kind))
4377 return getCursorStmt(C)->getSourceRange();
4378
4379 if (clang_isAttribute(C.kind))
4380 return getCursorAttr(C)->getRange();
4381
4382 if (C.kind == CXCursor_PreprocessingDirective)
4383 return cxcursor::getCursorPreprocessingDirective(C);
4384
4385 if (C.kind == CXCursor_MacroExpansion) {
4386 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004387 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004388 return TU->mapRangeFromPreamble(Range);
4389 }
4390
4391 if (C.kind == CXCursor_MacroDefinition) {
4392 ASTUnit *TU = getCursorASTUnit(C);
4393 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4394 return TU->mapRangeFromPreamble(Range);
4395 }
4396
4397 if (C.kind == CXCursor_InclusionDirective) {
4398 ASTUnit *TU = getCursorASTUnit(C);
4399 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4400 return TU->mapRangeFromPreamble(Range);
4401 }
4402
4403 if (C.kind == CXCursor_TranslationUnit) {
4404 ASTUnit *TU = getCursorASTUnit(C);
4405 FileID MainID = TU->getSourceManager().getMainFileID();
4406 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4407 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4408 return SourceRange(Start, End);
4409 }
4410
4411 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004412 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004413 if (!D)
4414 return SourceRange();
4415
4416 SourceRange R = D->getSourceRange();
4417 // FIXME: Multiple variables declared in a single declaration
4418 // currently lack the information needed to correctly determine their
4419 // ranges when accounting for the type-specifier. We use context
4420 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4421 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004422 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004423 if (!cxcursor::isFirstInDeclGroup(C))
4424 R.setBegin(VD->getLocation());
4425 }
4426 return R;
4427 }
4428 return SourceRange();
4429}
4430
4431/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4432/// the decl-specifier-seq for declarations.
4433static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4434 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004435 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004436 if (!D)
4437 return SourceRange();
4438
4439 SourceRange R = D->getSourceRange();
4440
4441 // Adjust the start of the location for declarations preceded by
4442 // declaration specifiers.
4443 SourceLocation StartLoc;
4444 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4445 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4446 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004447 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004448 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4449 StartLoc = TI->getTypeLoc().getLocStart();
4450 }
4451
4452 if (StartLoc.isValid() && R.getBegin().isValid() &&
4453 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4454 R.setBegin(StartLoc);
4455
4456 // FIXME: Multiple variables declared in a single declaration
4457 // currently lack the information needed to correctly determine their
4458 // ranges when accounting for the type-specifier. We use context
4459 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4460 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004461 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004462 if (!cxcursor::isFirstInDeclGroup(C))
4463 R.setBegin(VD->getLocation());
4464 }
4465
4466 return R;
4467 }
4468
4469 return getRawCursorExtent(C);
4470}
4471
4472extern "C" {
4473
4474CXSourceRange clang_getCursorExtent(CXCursor C) {
4475 SourceRange R = getRawCursorExtent(C);
4476 if (R.isInvalid())
4477 return clang_getNullRange();
4478
4479 return cxloc::translateSourceRange(getCursorContext(C), R);
4480}
4481
4482CXCursor clang_getCursorReferenced(CXCursor C) {
4483 if (clang_isInvalid(C.kind))
4484 return clang_getNullCursor();
4485
4486 CXTranslationUnit tu = getCursorTU(C);
4487 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004488 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004489 if (!D)
4490 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004491 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004492 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004493 if (const ObjCPropertyImplDecl *PropImpl =
4494 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004495 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4496 return MakeCXCursor(Property, tu);
4497
4498 return C;
4499 }
4500
4501 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004502 const Expr *E = getCursorExpr(C);
4503 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004504 if (D) {
4505 CXCursor declCursor = MakeCXCursor(D, tu);
4506 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4507 declCursor);
4508 return declCursor;
4509 }
4510
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004511 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004512 return MakeCursorOverloadedDeclRef(Ovl, tu);
4513
4514 return clang_getNullCursor();
4515 }
4516
4517 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004518 const Stmt *S = getCursorStmt(C);
4519 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004520 if (LabelDecl *label = Goto->getLabel())
4521 if (LabelStmt *labelS = label->getStmt())
4522 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4523
4524 return clang_getNullCursor();
4525 }
4526
4527 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004528 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004529 return MakeMacroDefinitionCursor(Def, tu);
4530 }
4531
4532 if (!clang_isReference(C.kind))
4533 return clang_getNullCursor();
4534
4535 switch (C.kind) {
4536 case CXCursor_ObjCSuperClassRef:
4537 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4538
4539 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004540 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4541 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004542 return MakeCXCursor(Def, tu);
4543
4544 return MakeCXCursor(Prot, tu);
4545 }
4546
4547 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004548 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4549 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004550 return MakeCXCursor(Def, tu);
4551
4552 return MakeCXCursor(Class, tu);
4553 }
4554
4555 case CXCursor_TypeRef:
4556 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4557
4558 case CXCursor_TemplateRef:
4559 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4560
4561 case CXCursor_NamespaceRef:
4562 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4563
4564 case CXCursor_MemberRef:
4565 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4566
4567 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004568 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004569 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4570 tu ));
4571 }
4572
4573 case CXCursor_LabelRef:
4574 // FIXME: We end up faking the "parent" declaration here because we
4575 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004576 return MakeCXCursor(getCursorLabelRef(C).first,
4577 cxtu::getASTUnit(tu)->getASTContext()
4578 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004579 tu);
4580
4581 case CXCursor_OverloadedDeclRef:
4582 return C;
4583
4584 case CXCursor_VariableRef:
4585 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4586
4587 default:
4588 // We would prefer to enumerate all non-reference cursor kinds here.
4589 llvm_unreachable("Unhandled reference cursor kind");
4590 }
4591}
4592
4593CXCursor clang_getCursorDefinition(CXCursor C) {
4594 if (clang_isInvalid(C.kind))
4595 return clang_getNullCursor();
4596
4597 CXTranslationUnit TU = getCursorTU(C);
4598
4599 bool WasReference = false;
4600 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4601 C = clang_getCursorReferenced(C);
4602 WasReference = true;
4603 }
4604
4605 if (C.kind == CXCursor_MacroExpansion)
4606 return clang_getCursorReferenced(C);
4607
4608 if (!clang_isDeclaration(C.kind))
4609 return clang_getNullCursor();
4610
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004611 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004612 if (!D)
4613 return clang_getNullCursor();
4614
4615 switch (D->getKind()) {
4616 // Declaration kinds that don't really separate the notions of
4617 // declaration and definition.
4618 case Decl::Namespace:
4619 case Decl::Typedef:
4620 case Decl::TypeAlias:
4621 case Decl::TypeAliasTemplate:
4622 case Decl::TemplateTypeParm:
4623 case Decl::EnumConstant:
4624 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004625 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004626 case Decl::IndirectField:
4627 case Decl::ObjCIvar:
4628 case Decl::ObjCAtDefsField:
4629 case Decl::ImplicitParam:
4630 case Decl::ParmVar:
4631 case Decl::NonTypeTemplateParm:
4632 case Decl::TemplateTemplateParm:
4633 case Decl::ObjCCategoryImpl:
4634 case Decl::ObjCImplementation:
4635 case Decl::AccessSpec:
4636 case Decl::LinkageSpec:
4637 case Decl::ObjCPropertyImpl:
4638 case Decl::FileScopeAsm:
4639 case Decl::StaticAssert:
4640 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004641 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004642 case Decl::Label: // FIXME: Is this right??
4643 case Decl::ClassScopeFunctionSpecialization:
4644 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004645 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004646 return C;
4647
4648 // Declaration kinds that don't make any sense here, but are
4649 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004650 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004651 case Decl::TranslationUnit:
4652 break;
4653
4654 // Declaration kinds for which the definition is not resolvable.
4655 case Decl::UnresolvedUsingTypename:
4656 case Decl::UnresolvedUsingValue:
4657 break;
4658
4659 case Decl::UsingDirective:
4660 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4661 TU);
4662
4663 case Decl::NamespaceAlias:
4664 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4665
4666 case Decl::Enum:
4667 case Decl::Record:
4668 case Decl::CXXRecord:
4669 case Decl::ClassTemplateSpecialization:
4670 case Decl::ClassTemplatePartialSpecialization:
4671 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4672 return MakeCXCursor(Def, TU);
4673 return clang_getNullCursor();
4674
4675 case Decl::Function:
4676 case Decl::CXXMethod:
4677 case Decl::CXXConstructor:
4678 case Decl::CXXDestructor:
4679 case Decl::CXXConversion: {
4680 const FunctionDecl *Def = 0;
4681 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004682 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004683 return clang_getNullCursor();
4684 }
4685
Larisse Voufo39a1e502013-08-06 01:03:05 +00004686 case Decl::Var:
4687 case Decl::VarTemplateSpecialization:
4688 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004689 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004690 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 return MakeCXCursor(Def, TU);
4692 return clang_getNullCursor();
4693 }
4694
4695 case Decl::FunctionTemplate: {
4696 const FunctionDecl *Def = 0;
4697 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4698 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4699 return clang_getNullCursor();
4700 }
4701
4702 case Decl::ClassTemplate: {
4703 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4704 ->getDefinition())
4705 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4706 TU);
4707 return clang_getNullCursor();
4708 }
4709
Larisse Voufo39a1e502013-08-06 01:03:05 +00004710 case Decl::VarTemplate: {
4711 if (VarDecl *Def =
4712 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4713 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4714 return clang_getNullCursor();
4715 }
4716
Guy Benyei11169dd2012-12-18 14:30:41 +00004717 case Decl::Using:
4718 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4719 D->getLocation(), TU);
4720
4721 case Decl::UsingShadow:
4722 return clang_getCursorDefinition(
4723 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4724 TU));
4725
4726 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004727 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004728 if (Method->isThisDeclarationADefinition())
4729 return C;
4730
4731 // Dig out the method definition in the associated
4732 // @implementation, if we have it.
4733 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004734 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004735 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4736 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4737 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4738 Method->isInstanceMethod()))
4739 if (Def->isThisDeclarationADefinition())
4740 return MakeCXCursor(Def, TU);
4741
4742 return clang_getNullCursor();
4743 }
4744
4745 case Decl::ObjCCategory:
4746 if (ObjCCategoryImplDecl *Impl
4747 = cast<ObjCCategoryDecl>(D)->getImplementation())
4748 return MakeCXCursor(Impl, TU);
4749 return clang_getNullCursor();
4750
4751 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004752 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004753 return MakeCXCursor(Def, TU);
4754 return clang_getNullCursor();
4755
4756 case Decl::ObjCInterface: {
4757 // There are two notions of a "definition" for an Objective-C
4758 // class: the interface and its implementation. When we resolved a
4759 // reference to an Objective-C class, produce the @interface as
4760 // the definition; when we were provided with the interface,
4761 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004762 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004763 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004764 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004765 return MakeCXCursor(Def, TU);
4766 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4767 return MakeCXCursor(Impl, TU);
4768 return clang_getNullCursor();
4769 }
4770
4771 case Decl::ObjCProperty:
4772 // FIXME: We don't really know where to find the
4773 // ObjCPropertyImplDecls that implement this property.
4774 return clang_getNullCursor();
4775
4776 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004777 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004778 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004779 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004780 return MakeCXCursor(Def, TU);
4781
4782 return clang_getNullCursor();
4783
4784 case Decl::Friend:
4785 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4786 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4787 return clang_getNullCursor();
4788
4789 case Decl::FriendTemplate:
4790 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4791 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4792 return clang_getNullCursor();
4793 }
4794
4795 return clang_getNullCursor();
4796}
4797
4798unsigned clang_isCursorDefinition(CXCursor C) {
4799 if (!clang_isDeclaration(C.kind))
4800 return 0;
4801
4802 return clang_getCursorDefinition(C) == C;
4803}
4804
4805CXCursor clang_getCanonicalCursor(CXCursor C) {
4806 if (!clang_isDeclaration(C.kind))
4807 return C;
4808
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004809 if (const Decl *D = getCursorDecl(C)) {
4810 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004811 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4812 return MakeCXCursor(CatD, getCursorTU(C));
4813
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004814 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4815 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004816 return MakeCXCursor(IFD, getCursorTU(C));
4817
4818 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4819 }
4820
4821 return C;
4822}
4823
4824int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4825 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4826}
4827
4828unsigned clang_getNumOverloadedDecls(CXCursor C) {
4829 if (C.kind != CXCursor_OverloadedDeclRef)
4830 return 0;
4831
4832 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004833 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004834 return E->getNumDecls();
4835
4836 if (OverloadedTemplateStorage *S
4837 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4838 return S->size();
4839
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004840 const Decl *D = Storage.get<const Decl *>();
4841 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004842 return Using->shadow_size();
4843
4844 return 0;
4845}
4846
4847CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4848 if (cursor.kind != CXCursor_OverloadedDeclRef)
4849 return clang_getNullCursor();
4850
4851 if (index >= clang_getNumOverloadedDecls(cursor))
4852 return clang_getNullCursor();
4853
4854 CXTranslationUnit TU = getCursorTU(cursor);
4855 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004856 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004857 return MakeCXCursor(E->decls_begin()[index], TU);
4858
4859 if (OverloadedTemplateStorage *S
4860 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4861 return MakeCXCursor(S->begin()[index], TU);
4862
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004863 const Decl *D = Storage.get<const Decl *>();
4864 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004865 // FIXME: This is, unfortunately, linear time.
4866 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4867 std::advance(Pos, index);
4868 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4869 }
4870
4871 return clang_getNullCursor();
4872}
4873
4874void clang_getDefinitionSpellingAndExtent(CXCursor C,
4875 const char **startBuf,
4876 const char **endBuf,
4877 unsigned *startLine,
4878 unsigned *startColumn,
4879 unsigned *endLine,
4880 unsigned *endColumn) {
4881 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004882 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004883 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4884
4885 SourceManager &SM = FD->getASTContext().getSourceManager();
4886 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4887 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4888 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4889 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4890 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4891 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4892}
4893
4894
4895CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4896 unsigned PieceIndex) {
4897 RefNamePieces Pieces;
4898
4899 switch (C.kind) {
4900 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004901 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004902 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4903 E->getQualifierLoc().getSourceRange());
4904 break;
4905
4906 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004907 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004908 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4909 E->getQualifierLoc().getSourceRange(),
4910 E->getOptionalExplicitTemplateArgs());
4911 break;
4912
4913 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004914 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004915 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004916 const Expr *Callee = OCE->getCallee();
4917 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004918 Callee = ICE->getSubExpr();
4919
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004920 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004921 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4922 DRE->getQualifierLoc().getSourceRange());
4923 }
4924 break;
4925
4926 default:
4927 break;
4928 }
4929
4930 if (Pieces.empty()) {
4931 if (PieceIndex == 0)
4932 return clang_getCursorExtent(C);
4933 } else if (PieceIndex < Pieces.size()) {
4934 SourceRange R = Pieces[PieceIndex];
4935 if (R.isValid())
4936 return cxloc::translateSourceRange(getCursorContext(C), R);
4937 }
4938
4939 return clang_getNullRange();
4940}
4941
4942void clang_enableStackTraces(void) {
4943 llvm::sys::PrintStackTraceOnErrorSignal();
4944}
4945
4946void clang_executeOnThread(void (*fn)(void*), void *user_data,
4947 unsigned stack_size) {
4948 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4949}
4950
4951} // end: extern "C"
4952
4953//===----------------------------------------------------------------------===//
4954// Token-based Operations.
4955//===----------------------------------------------------------------------===//
4956
4957/* CXToken layout:
4958 * int_data[0]: a CXTokenKind
4959 * int_data[1]: starting token location
4960 * int_data[2]: token length
4961 * int_data[3]: reserved
4962 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4963 * otherwise unused.
4964 */
4965extern "C" {
4966
4967CXTokenKind clang_getTokenKind(CXToken CXTok) {
4968 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4969}
4970
4971CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4972 switch (clang_getTokenKind(CXTok)) {
4973 case CXToken_Identifier:
4974 case CXToken_Keyword:
4975 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004976 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004977 ->getNameStart());
4978
4979 case CXToken_Literal: {
4980 // We have stashed the starting pointer in the ptr_data field. Use it.
4981 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004982 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004983 }
4984
4985 case CXToken_Punctuation:
4986 case CXToken_Comment:
4987 break;
4988 }
4989
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004990 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004991 LOG_BAD_TU(TU);
4992 return cxstring::createEmpty();
4993 }
4994
Guy Benyei11169dd2012-12-18 14:30:41 +00004995 // We have to find the starting buffer pointer the hard way, by
4996 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004997 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004998 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004999 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005000
5001 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5002 std::pair<FileID, unsigned> LocInfo
5003 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5004 bool Invalid = false;
5005 StringRef Buffer
5006 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5007 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005008 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005009
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005010 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005011}
5012
5013CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005014 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005015 LOG_BAD_TU(TU);
5016 return clang_getNullLocation();
5017 }
5018
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005019 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005020 if (!CXXUnit)
5021 return clang_getNullLocation();
5022
5023 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5024 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5025}
5026
5027CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005028 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005029 LOG_BAD_TU(TU);
5030 return clang_getNullRange();
5031 }
5032
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005033 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005034 if (!CXXUnit)
5035 return clang_getNullRange();
5036
5037 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5038 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5039}
5040
5041static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5042 SmallVectorImpl<CXToken> &CXTokens) {
5043 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5044 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005045 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005046 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005047 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005048
5049 // Cannot tokenize across files.
5050 if (BeginLocInfo.first != EndLocInfo.first)
5051 return;
5052
5053 // Create a lexer
5054 bool Invalid = false;
5055 StringRef Buffer
5056 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5057 if (Invalid)
5058 return;
5059
5060 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5061 CXXUnit->getASTContext().getLangOpts(),
5062 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5063 Lex.SetCommentRetentionState(true);
5064
5065 // Lex tokens until we hit the end of the range.
5066 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5067 Token Tok;
5068 bool previousWasAt = false;
5069 do {
5070 // Lex the next token
5071 Lex.LexFromRawLexer(Tok);
5072 if (Tok.is(tok::eof))
5073 break;
5074
5075 // Initialize the CXToken.
5076 CXToken CXTok;
5077
5078 // - Common fields
5079 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5080 CXTok.int_data[2] = Tok.getLength();
5081 CXTok.int_data[3] = 0;
5082
5083 // - Kind-specific fields
5084 if (Tok.isLiteral()) {
5085 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005086 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005087 } else if (Tok.is(tok::raw_identifier)) {
5088 // Lookup the identifier to determine whether we have a keyword.
5089 IdentifierInfo *II
5090 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5091
5092 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5093 CXTok.int_data[0] = CXToken_Keyword;
5094 }
5095 else {
5096 CXTok.int_data[0] = Tok.is(tok::identifier)
5097 ? CXToken_Identifier
5098 : CXToken_Keyword;
5099 }
5100 CXTok.ptr_data = II;
5101 } else if (Tok.is(tok::comment)) {
5102 CXTok.int_data[0] = CXToken_Comment;
5103 CXTok.ptr_data = 0;
5104 } else {
5105 CXTok.int_data[0] = CXToken_Punctuation;
5106 CXTok.ptr_data = 0;
5107 }
5108 CXTokens.push_back(CXTok);
5109 previousWasAt = Tok.is(tok::at);
5110 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5111}
5112
5113void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5114 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005115 LOG_FUNC_SECTION {
5116 *Log << TU << ' ' << Range;
5117 }
5118
Guy Benyei11169dd2012-12-18 14:30:41 +00005119 if (Tokens)
5120 *Tokens = 0;
5121 if (NumTokens)
5122 *NumTokens = 0;
5123
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005124 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005125 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005126 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005127 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005128
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005129 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005130 if (!CXXUnit || !Tokens || !NumTokens)
5131 return;
5132
5133 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5134
5135 SourceRange R = cxloc::translateCXSourceRange(Range);
5136 if (R.isInvalid())
5137 return;
5138
5139 SmallVector<CXToken, 32> CXTokens;
5140 getTokens(CXXUnit, R, CXTokens);
5141
5142 if (CXTokens.empty())
5143 return;
5144
5145 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5146 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5147 *NumTokens = CXTokens.size();
5148}
5149
5150void clang_disposeTokens(CXTranslationUnit TU,
5151 CXToken *Tokens, unsigned NumTokens) {
5152 free(Tokens);
5153}
5154
5155} // end: extern "C"
5156
5157//===----------------------------------------------------------------------===//
5158// Token annotation APIs.
5159//===----------------------------------------------------------------------===//
5160
Guy Benyei11169dd2012-12-18 14:30:41 +00005161static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5162 CXCursor parent,
5163 CXClientData client_data);
5164static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5165 CXClientData client_data);
5166
5167namespace {
5168class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005169 CXToken *Tokens;
5170 CXCursor *Cursors;
5171 unsigned NumTokens;
5172 unsigned TokIdx;
5173 unsigned PreprocessingTokIdx;
5174 CursorVisitor AnnotateVis;
5175 SourceManager &SrcMgr;
5176 bool HasContextSensitiveKeywords;
5177
5178 struct PostChildrenInfo {
5179 CXCursor Cursor;
5180 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005181 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005182 unsigned BeforeChildrenTokenIdx;
5183 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005184 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005185
5186 CXToken &getTok(unsigned Idx) {
5187 assert(Idx < NumTokens);
5188 return Tokens[Idx];
5189 }
5190 const CXToken &getTok(unsigned Idx) const {
5191 assert(Idx < NumTokens);
5192 return Tokens[Idx];
5193 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005194 bool MoreTokens() const { return TokIdx < NumTokens; }
5195 unsigned NextToken() const { return TokIdx; }
5196 void AdvanceToken() { ++TokIdx; }
5197 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005198 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005199 }
5200 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005201 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005202 }
5203 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005204 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005205 }
5206
5207 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005208 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005209 SourceRange);
5210
5211public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005212 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005213 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005214 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005215 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005216 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005217 AnnotateTokensVisitor, this,
5218 /*VisitPreprocessorLast=*/true,
5219 /*VisitIncludedEntities=*/false,
5220 RegionOfInterest,
5221 /*VisitDeclsOnly=*/false,
5222 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005223 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 HasContextSensitiveKeywords(false) { }
5225
5226 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5227 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5228 bool postVisitChildren(CXCursor cursor);
5229 void AnnotateTokens();
5230
5231 /// \brief Determine whether the annotator saw any cursors that have
5232 /// context-sensitive keywords.
5233 bool hasContextSensitiveKeywords() const {
5234 return HasContextSensitiveKeywords;
5235 }
5236
5237 ~AnnotateTokensWorker() {
5238 assert(PostChildrenInfos.empty());
5239 }
5240};
5241}
5242
5243void AnnotateTokensWorker::AnnotateTokens() {
5244 // Walk the AST within the region of interest, annotating tokens
5245 // along the way.
5246 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005247}
Guy Benyei11169dd2012-12-18 14:30:41 +00005248
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005249static inline void updateCursorAnnotation(CXCursor &Cursor,
5250 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005251 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005252 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005253 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005254}
5255
5256/// \brief It annotates and advances tokens with a cursor until the comparison
5257//// between the cursor location and the source range is the same as
5258/// \arg compResult.
5259///
5260/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5261/// Pass RangeOverlap to annotate tokens inside a range.
5262void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5263 RangeComparisonResult compResult,
5264 SourceRange range) {
5265 while (MoreTokens()) {
5266 const unsigned I = NextToken();
5267 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005268 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5269 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005270
5271 SourceLocation TokLoc = GetTokenLoc(I);
5272 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005273 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005274 AdvanceToken();
5275 continue;
5276 }
5277 break;
5278 }
5279}
5280
5281/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005282/// \returns true if it advanced beyond all macro tokens, false otherwise.
5283bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005284 CXCursor updateC,
5285 RangeComparisonResult compResult,
5286 SourceRange range) {
5287 assert(MoreTokens());
5288 assert(isFunctionMacroToken(NextToken()) &&
5289 "Should be called only for macro arg tokens");
5290
5291 // This works differently than annotateAndAdvanceTokens; because expanded
5292 // macro arguments can have arbitrary translation-unit source order, we do not
5293 // advance the token index one by one until a token fails the range test.
5294 // We only advance once past all of the macro arg tokens if all of them
5295 // pass the range test. If one of them fails we keep the token index pointing
5296 // at the start of the macro arg tokens so that the failing token will be
5297 // annotated by a subsequent annotation try.
5298
5299 bool atLeastOneCompFail = false;
5300
5301 unsigned I = NextToken();
5302 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5303 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5304 if (TokLoc.isFileID())
5305 continue; // not macro arg token, it's parens or comma.
5306 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5307 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5308 Cursors[I] = updateC;
5309 } else
5310 atLeastOneCompFail = true;
5311 }
5312
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005313 if (atLeastOneCompFail)
5314 return false;
5315
5316 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5317 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005318}
5319
5320enum CXChildVisitResult
5321AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005322 SourceRange cursorRange = getRawCursorExtent(cursor);
5323 if (cursorRange.isInvalid())
5324 return CXChildVisit_Recurse;
5325
5326 if (!HasContextSensitiveKeywords) {
5327 // Objective-C properties can have context-sensitive keywords.
5328 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005329 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005330 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5331 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5332 }
5333 // Objective-C methods can have context-sensitive keywords.
5334 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5335 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005336 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005337 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5338 if (Method->getObjCDeclQualifier())
5339 HasContextSensitiveKeywords = true;
5340 else {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005341 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5342 PEnd = Method->param_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00005343 P != PEnd; ++P) {
5344 if ((*P)->getObjCDeclQualifier()) {
5345 HasContextSensitiveKeywords = true;
5346 break;
5347 }
5348 }
5349 }
5350 }
5351 }
5352 // C++ methods can have context-sensitive keywords.
5353 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005354 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005355 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5356 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5357 HasContextSensitiveKeywords = true;
5358 }
5359 }
5360 // C++ classes can have context-sensitive keywords.
5361 else if (cursor.kind == CXCursor_StructDecl ||
5362 cursor.kind == CXCursor_ClassDecl ||
5363 cursor.kind == CXCursor_ClassTemplate ||
5364 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005365 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005366 if (D->hasAttr<FinalAttr>())
5367 HasContextSensitiveKeywords = true;
5368 }
5369 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005370
5371 // Don't override a property annotation with its getter/setter method.
5372 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5373 parent.kind == CXCursor_ObjCPropertyDecl)
5374 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005375
5376 if (clang_isPreprocessing(cursor.kind)) {
5377 // Items in the preprocessing record are kept separate from items in
5378 // declarations, so we keep a separate token index.
5379 unsigned SavedTokIdx = TokIdx;
5380 TokIdx = PreprocessingTokIdx;
5381
5382 // Skip tokens up until we catch up to the beginning of the preprocessing
5383 // entry.
5384 while (MoreTokens()) {
5385 const unsigned I = NextToken();
5386 SourceLocation TokLoc = GetTokenLoc(I);
5387 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5388 case RangeBefore:
5389 AdvanceToken();
5390 continue;
5391 case RangeAfter:
5392 case RangeOverlap:
5393 break;
5394 }
5395 break;
5396 }
5397
5398 // Look at all of the tokens within this range.
5399 while (MoreTokens()) {
5400 const unsigned I = NextToken();
5401 SourceLocation TokLoc = GetTokenLoc(I);
5402 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5403 case RangeBefore:
5404 llvm_unreachable("Infeasible");
5405 case RangeAfter:
5406 break;
5407 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005408 // For macro expansions, just note where the beginning of the macro
5409 // expansion occurs.
5410 if (cursor.kind == CXCursor_MacroExpansion) {
5411 if (TokLoc == cursorRange.getBegin())
5412 Cursors[I] = cursor;
5413 AdvanceToken();
5414 break;
5415 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005416 // We may have already annotated macro names inside macro definitions.
5417 if (Cursors[I].kind != CXCursor_MacroExpansion)
5418 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005419 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005420 continue;
5421 }
5422 break;
5423 }
5424
5425 // Save the preprocessing token index; restore the non-preprocessing
5426 // token index.
5427 PreprocessingTokIdx = TokIdx;
5428 TokIdx = SavedTokIdx;
5429 return CXChildVisit_Recurse;
5430 }
5431
5432 if (cursorRange.isInvalid())
5433 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005434
5435 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005436 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005437 const enum CXCursorKind K = clang_getCursorKind(parent);
5438 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005439 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5440 // Attributes are annotated out-of-order, skip tokens until we reach it.
5441 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005442 ? clang_getNullCursor() : parent;
5443
5444 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5445
5446 // Avoid having the cursor of an expression "overwrite" the annotation of the
5447 // variable declaration that it belongs to.
5448 // This can happen for C++ constructor expressions whose range generally
5449 // include the variable declaration, e.g.:
5450 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005451 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005452 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005453 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005454 const unsigned I = NextToken();
5455 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5456 E->getLocStart() == D->getLocation() &&
5457 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005458 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005459 AdvanceToken();
5460 }
5461 }
5462 }
5463
5464 // Before recursing into the children keep some state that we are going
5465 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5466 // extra work after the child nodes are visited.
5467 // Note that we don't call VisitChildren here to avoid traversing statements
5468 // code-recursively which can blow the stack.
5469
5470 PostChildrenInfo Info;
5471 Info.Cursor = cursor;
5472 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005473 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005474 Info.BeforeChildrenTokenIdx = NextToken();
5475 PostChildrenInfos.push_back(Info);
5476
5477 return CXChildVisit_Recurse;
5478}
5479
5480bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5481 if (PostChildrenInfos.empty())
5482 return false;
5483 const PostChildrenInfo &Info = PostChildrenInfos.back();
5484 if (!clang_equalCursors(Info.Cursor, cursor))
5485 return false;
5486
5487 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5488 const unsigned AfterChildren = NextToken();
5489 SourceRange cursorRange = Info.CursorRange;
5490
5491 // Scan the tokens that are at the end of the cursor, but are not captured
5492 // but the child cursors.
5493 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5494
5495 // Scan the tokens that are at the beginning of the cursor, but are not
5496 // capture by the child cursors.
5497 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5498 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5499 break;
5500
5501 Cursors[I] = cursor;
5502 }
5503
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005504 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5505 // encountered the attribute cursor.
5506 if (clang_isAttribute(cursor.kind))
5507 TokIdx = Info.BeforeReachingCursorIdx;
5508
Guy Benyei11169dd2012-12-18 14:30:41 +00005509 PostChildrenInfos.pop_back();
5510 return false;
5511}
5512
5513static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5514 CXCursor parent,
5515 CXClientData client_data) {
5516 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5517}
5518
5519static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5520 CXClientData client_data) {
5521 return static_cast<AnnotateTokensWorker*>(client_data)->
5522 postVisitChildren(cursor);
5523}
5524
5525namespace {
5526
5527/// \brief Uses the macro expansions in the preprocessing record to find
5528/// and mark tokens that are macro arguments. This info is used by the
5529/// AnnotateTokensWorker.
5530class MarkMacroArgTokensVisitor {
5531 SourceManager &SM;
5532 CXToken *Tokens;
5533 unsigned NumTokens;
5534 unsigned CurIdx;
5535
5536public:
5537 MarkMacroArgTokensVisitor(SourceManager &SM,
5538 CXToken *tokens, unsigned numTokens)
5539 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5540
5541 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5542 if (cursor.kind != CXCursor_MacroExpansion)
5543 return CXChildVisit_Continue;
5544
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005545 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005546 if (macroRange.getBegin() == macroRange.getEnd())
5547 return CXChildVisit_Continue; // it's not a function macro.
5548
5549 for (; CurIdx < NumTokens; ++CurIdx) {
5550 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5551 macroRange.getBegin()))
5552 break;
5553 }
5554
5555 if (CurIdx == NumTokens)
5556 return CXChildVisit_Break;
5557
5558 for (; CurIdx < NumTokens; ++CurIdx) {
5559 SourceLocation tokLoc = getTokenLoc(CurIdx);
5560 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5561 break;
5562
5563 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5564 }
5565
5566 if (CurIdx == NumTokens)
5567 return CXChildVisit_Break;
5568
5569 return CXChildVisit_Continue;
5570 }
5571
5572private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005573 CXToken &getTok(unsigned Idx) {
5574 assert(Idx < NumTokens);
5575 return Tokens[Idx];
5576 }
5577 const CXToken &getTok(unsigned Idx) const {
5578 assert(Idx < NumTokens);
5579 return Tokens[Idx];
5580 }
5581
Guy Benyei11169dd2012-12-18 14:30:41 +00005582 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005583 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005584 }
5585
5586 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5587 // The third field is reserved and currently not used. Use it here
5588 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005589 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005590 }
5591};
5592
5593} // end anonymous namespace
5594
5595static CXChildVisitResult
5596MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5597 CXClientData client_data) {
5598 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5599 parent);
5600}
5601
5602namespace {
5603 struct clang_annotateTokens_Data {
5604 CXTranslationUnit TU;
5605 ASTUnit *CXXUnit;
5606 CXToken *Tokens;
5607 unsigned NumTokens;
5608 CXCursor *Cursors;
5609 };
5610}
5611
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005612/// \brief Used by \c annotatePreprocessorTokens.
5613/// \returns true if lexing was finished, false otherwise.
5614static bool lexNext(Lexer &Lex, Token &Tok,
5615 unsigned &NextIdx, unsigned NumTokens) {
5616 if (NextIdx >= NumTokens)
5617 return true;
5618
5619 ++NextIdx;
5620 Lex.LexFromRawLexer(Tok);
5621 if (Tok.is(tok::eof))
5622 return true;
5623
5624 return false;
5625}
5626
Guy Benyei11169dd2012-12-18 14:30:41 +00005627static void annotatePreprocessorTokens(CXTranslationUnit TU,
5628 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005629 CXCursor *Cursors,
5630 CXToken *Tokens,
5631 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005632 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005633
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005634 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005635 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5636 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005637 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005638 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005639 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005640
5641 if (BeginLocInfo.first != EndLocInfo.first)
5642 return;
5643
5644 StringRef Buffer;
5645 bool Invalid = false;
5646 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5647 if (Buffer.empty() || Invalid)
5648 return;
5649
5650 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5651 CXXUnit->getASTContext().getLangOpts(),
5652 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5653 Buffer.end());
5654 Lex.SetCommentRetentionState(true);
5655
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005656 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005657 // Lex tokens in raw mode until we hit the end of the range, to avoid
5658 // entering #includes or expanding macros.
5659 while (true) {
5660 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005661 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5662 break;
5663 unsigned TokIdx = NextIdx-1;
5664 assert(Tok.getLocation() ==
5665 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005666
5667 reprocess:
5668 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005669 // We have found a preprocessing directive. Annotate the tokens
5670 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005671 //
5672 // FIXME: Some simple tests here could identify macro definitions and
5673 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005674
5675 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005676 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5677 break;
5678
5679 MacroInfo *MI = 0;
5680 if (Tok.is(tok::raw_identifier) &&
5681 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5682 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5683 break;
5684
5685 if (Tok.is(tok::raw_identifier)) {
5686 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5687 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5688 SourceLocation MappedTokLoc =
5689 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5690 MI = getMacroInfo(II, MappedTokLoc, TU);
5691 }
5692 }
5693
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005694 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005695 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005696 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5697 finished = true;
5698 break;
5699 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005700 // If we are in a macro definition, check if the token was ever a
5701 // macro name and annotate it if that's the case.
5702 if (MI) {
5703 SourceLocation SaveLoc = Tok.getLocation();
5704 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5705 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5706 Tok.setLocation(SaveLoc);
5707 if (MacroDef)
5708 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5709 Tok.getLocation(), TU);
5710 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005711 } while (!Tok.isAtStartOfLine());
5712
5713 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5714 assert(TokIdx <= LastIdx);
5715 SourceLocation EndLoc =
5716 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5717 CXCursor Cursor =
5718 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5719
5720 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005721 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005722
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005723 if (finished)
5724 break;
5725 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005726 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005727 }
5728}
5729
5730// This gets run a separate thread to avoid stack blowout.
5731static void clang_annotateTokensImpl(void *UserData) {
5732 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5733 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5734 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5735 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5736 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5737
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005738 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005739 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5740 setThreadBackgroundPriority();
5741
5742 // Determine the region of interest, which contains all of the tokens.
5743 SourceRange RegionOfInterest;
5744 RegionOfInterest.setBegin(
5745 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5746 RegionOfInterest.setEnd(
5747 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5748 Tokens[NumTokens-1])));
5749
Guy Benyei11169dd2012-12-18 14:30:41 +00005750 // Relex the tokens within the source range to look for preprocessing
5751 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005752 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005753
5754 // If begin location points inside a macro argument, set it to the expansion
5755 // location so we can have the full context when annotating semantically.
5756 {
5757 SourceManager &SM = CXXUnit->getSourceManager();
5758 SourceLocation Loc =
5759 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5760 if (Loc.isMacroID())
5761 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5762 }
5763
Guy Benyei11169dd2012-12-18 14:30:41 +00005764 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5765 // Search and mark tokens that are macro argument expansions.
5766 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5767 Tokens, NumTokens);
5768 CursorVisitor MacroArgMarker(TU,
5769 MarkMacroArgTokensVisitorDelegate, &Visitor,
5770 /*VisitPreprocessorLast=*/true,
5771 /*VisitIncludedEntities=*/false,
5772 RegionOfInterest);
5773 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5774 }
5775
5776 // Annotate all of the source locations in the region of interest that map to
5777 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005778 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005779
5780 // FIXME: We use a ridiculous stack size here because the data-recursion
5781 // algorithm uses a large stack frame than the non-data recursive version,
5782 // and AnnotationTokensWorker currently transforms the data-recursion
5783 // algorithm back into a traditional recursion by explicitly calling
5784 // VisitChildren(). We will need to remove this explicit recursive call.
5785 W.AnnotateTokens();
5786
5787 // If we ran into any entities that involve context-sensitive keywords,
5788 // take another pass through the tokens to mark them as such.
5789 if (W.hasContextSensitiveKeywords()) {
5790 for (unsigned I = 0; I != NumTokens; ++I) {
5791 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5792 continue;
5793
5794 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5795 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005796 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005797 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5798 if (Property->getPropertyAttributesAsWritten() != 0 &&
5799 llvm::StringSwitch<bool>(II->getName())
5800 .Case("readonly", true)
5801 .Case("assign", true)
5802 .Case("unsafe_unretained", true)
5803 .Case("readwrite", true)
5804 .Case("retain", true)
5805 .Case("copy", true)
5806 .Case("nonatomic", true)
5807 .Case("atomic", true)
5808 .Case("getter", true)
5809 .Case("setter", true)
5810 .Case("strong", true)
5811 .Case("weak", true)
5812 .Default(false))
5813 Tokens[I].int_data[0] = CXToken_Keyword;
5814 }
5815 continue;
5816 }
5817
5818 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5819 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5820 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5821 if (llvm::StringSwitch<bool>(II->getName())
5822 .Case("in", true)
5823 .Case("out", true)
5824 .Case("inout", true)
5825 .Case("oneway", true)
5826 .Case("bycopy", true)
5827 .Case("byref", true)
5828 .Default(false))
5829 Tokens[I].int_data[0] = CXToken_Keyword;
5830 continue;
5831 }
5832
5833 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5834 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5835 Tokens[I].int_data[0] = CXToken_Keyword;
5836 continue;
5837 }
5838 }
5839 }
5840}
5841
5842extern "C" {
5843
5844void clang_annotateTokens(CXTranslationUnit TU,
5845 CXToken *Tokens, unsigned NumTokens,
5846 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005847 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005848 LOG_BAD_TU(TU);
5849 return;
5850 }
5851 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005852 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005853 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005854 }
5855
5856 LOG_FUNC_SECTION {
5857 *Log << TU << ' ';
5858 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5859 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5860 *Log << clang_getRange(bloc, eloc);
5861 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005862
5863 // Any token we don't specifically annotate will have a NULL cursor.
5864 CXCursor C = clang_getNullCursor();
5865 for (unsigned I = 0; I != NumTokens; ++I)
5866 Cursors[I] = C;
5867
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005868 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005869 if (!CXXUnit)
5870 return;
5871
5872 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5873
5874 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5875 llvm::CrashRecoveryContext CRC;
5876 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5877 GetSafetyThreadStackSize() * 2)) {
5878 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5879 }
5880}
5881
5882} // end: extern "C"
5883
5884//===----------------------------------------------------------------------===//
5885// Operations for querying linkage of a cursor.
5886//===----------------------------------------------------------------------===//
5887
5888extern "C" {
5889CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5890 if (!clang_isDeclaration(cursor.kind))
5891 return CXLinkage_Invalid;
5892
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005893 const Decl *D = cxcursor::getCursorDecl(cursor);
5894 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005895 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005896 case NoLinkage:
5897 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005898 case InternalLinkage: return CXLinkage_Internal;
5899 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5900 case ExternalLinkage: return CXLinkage_External;
5901 };
5902
5903 return CXLinkage_Invalid;
5904}
5905} // end: extern "C"
5906
5907//===----------------------------------------------------------------------===//
5908// Operations for querying language of a cursor.
5909//===----------------------------------------------------------------------===//
5910
5911static CXLanguageKind getDeclLanguage(const Decl *D) {
5912 if (!D)
5913 return CXLanguage_C;
5914
5915 switch (D->getKind()) {
5916 default:
5917 break;
5918 case Decl::ImplicitParam:
5919 case Decl::ObjCAtDefsField:
5920 case Decl::ObjCCategory:
5921 case Decl::ObjCCategoryImpl:
5922 case Decl::ObjCCompatibleAlias:
5923 case Decl::ObjCImplementation:
5924 case Decl::ObjCInterface:
5925 case Decl::ObjCIvar:
5926 case Decl::ObjCMethod:
5927 case Decl::ObjCProperty:
5928 case Decl::ObjCPropertyImpl:
5929 case Decl::ObjCProtocol:
5930 return CXLanguage_ObjC;
5931 case Decl::CXXConstructor:
5932 case Decl::CXXConversion:
5933 case Decl::CXXDestructor:
5934 case Decl::CXXMethod:
5935 case Decl::CXXRecord:
5936 case Decl::ClassTemplate:
5937 case Decl::ClassTemplatePartialSpecialization:
5938 case Decl::ClassTemplateSpecialization:
5939 case Decl::Friend:
5940 case Decl::FriendTemplate:
5941 case Decl::FunctionTemplate:
5942 case Decl::LinkageSpec:
5943 case Decl::Namespace:
5944 case Decl::NamespaceAlias:
5945 case Decl::NonTypeTemplateParm:
5946 case Decl::StaticAssert:
5947 case Decl::TemplateTemplateParm:
5948 case Decl::TemplateTypeParm:
5949 case Decl::UnresolvedUsingTypename:
5950 case Decl::UnresolvedUsingValue:
5951 case Decl::Using:
5952 case Decl::UsingDirective:
5953 case Decl::UsingShadow:
5954 return CXLanguage_CPlusPlus;
5955 }
5956
5957 return CXLanguage_C;
5958}
5959
5960extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005961
5962static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5963 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5964 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005965
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005966 switch (D->getAvailability()) {
5967 case AR_Available:
5968 case AR_NotYetIntroduced:
5969 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005970 return getCursorAvailabilityForDecl(
5971 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005972 return CXAvailability_Available;
5973
5974 case AR_Deprecated:
5975 return CXAvailability_Deprecated;
5976
5977 case AR_Unavailable:
5978 return CXAvailability_NotAvailable;
5979 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005980
5981 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005982}
5983
Guy Benyei11169dd2012-12-18 14:30:41 +00005984enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5985 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005986 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5987 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005988
5989 return CXAvailability_Available;
5990}
5991
5992static CXVersion convertVersion(VersionTuple In) {
5993 CXVersion Out = { -1, -1, -1 };
5994 if (In.empty())
5995 return Out;
5996
5997 Out.Major = In.getMajor();
5998
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005999 Optional<unsigned> Minor = In.getMinor();
6000 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006001 Out.Minor = *Minor;
6002 else
6003 return Out;
6004
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006005 Optional<unsigned> Subminor = In.getSubminor();
6006 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006007 Out.Subminor = *Subminor;
6008
6009 return Out;
6010}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006011
6012static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6013 int *always_deprecated,
6014 CXString *deprecated_message,
6015 int *always_unavailable,
6016 CXString *unavailable_message,
6017 CXPlatformAvailability *availability,
6018 int availability_size) {
6019 bool HadAvailAttr = false;
6020 int N = 0;
6021 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
6022 ++A) {
6023 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
6024 HadAvailAttr = true;
6025 if (always_deprecated)
6026 *always_deprecated = 1;
6027 if (deprecated_message)
6028 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
6029 continue;
6030 }
6031
6032 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
6033 HadAvailAttr = true;
6034 if (always_unavailable)
6035 *always_unavailable = 1;
6036 if (unavailable_message) {
6037 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6038 }
6039 continue;
6040 }
6041
6042 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
6043 HadAvailAttr = true;
6044 if (N < availability_size) {
6045 availability[N].Platform
6046 = cxstring::createDup(Avail->getPlatform()->getName());
6047 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6048 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6049 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6050 availability[N].Unavailable = Avail->getUnavailable();
6051 availability[N].Message = cxstring::createDup(Avail->getMessage());
6052 }
6053 ++N;
6054 }
6055 }
6056
6057 if (!HadAvailAttr)
6058 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6059 return getCursorPlatformAvailabilityForDecl(
6060 cast<Decl>(EnumConst->getDeclContext()),
6061 always_deprecated,
6062 deprecated_message,
6063 always_unavailable,
6064 unavailable_message,
6065 availability,
6066 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006067
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006068 return N;
6069}
6070
Guy Benyei11169dd2012-12-18 14:30:41 +00006071int clang_getCursorPlatformAvailability(CXCursor cursor,
6072 int *always_deprecated,
6073 CXString *deprecated_message,
6074 int *always_unavailable,
6075 CXString *unavailable_message,
6076 CXPlatformAvailability *availability,
6077 int availability_size) {
6078 if (always_deprecated)
6079 *always_deprecated = 0;
6080 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006081 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006082 if (always_unavailable)
6083 *always_unavailable = 0;
6084 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006085 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006086
Guy Benyei11169dd2012-12-18 14:30:41 +00006087 if (!clang_isDeclaration(cursor.kind))
6088 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006089
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006090 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006091 if (!D)
6092 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006093
6094 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6095 deprecated_message,
6096 always_unavailable,
6097 unavailable_message,
6098 availability,
6099 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006100}
6101
6102void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6103 clang_disposeString(availability->Platform);
6104 clang_disposeString(availability->Message);
6105}
6106
6107CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6108 if (clang_isDeclaration(cursor.kind))
6109 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6110
6111 return CXLanguage_Invalid;
6112}
6113
6114 /// \brief If the given cursor is the "templated" declaration
6115 /// descibing a class or function template, return the class or
6116 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006117static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006118 if (!D)
6119 return 0;
6120
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006121 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006122 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6123 return FunTmpl;
6124
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006125 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006126 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6127 return ClassTmpl;
6128
6129 return D;
6130}
6131
6132CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6133 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006134 if (const Decl *D = getCursorDecl(cursor)) {
6135 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006136 if (!DC)
6137 return clang_getNullCursor();
6138
6139 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6140 getCursorTU(cursor));
6141 }
6142 }
6143
6144 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006145 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006146 return MakeCXCursor(D, getCursorTU(cursor));
6147 }
6148
6149 return clang_getNullCursor();
6150}
6151
6152CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6153 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006154 if (const Decl *D = getCursorDecl(cursor)) {
6155 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006156 if (!DC)
6157 return clang_getNullCursor();
6158
6159 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6160 getCursorTU(cursor));
6161 }
6162 }
6163
6164 // FIXME: Note that we can't easily compute the lexical context of a
6165 // statement or expression, so we return nothing.
6166 return clang_getNullCursor();
6167}
6168
6169CXFile clang_getIncludedFile(CXCursor cursor) {
6170 if (cursor.kind != CXCursor_InclusionDirective)
6171 return 0;
6172
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006173 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006174 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006175}
6176
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006177unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6178 if (C.kind != CXCursor_ObjCPropertyDecl)
6179 return CXObjCPropertyAttr_noattr;
6180
6181 unsigned Result = CXObjCPropertyAttr_noattr;
6182 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6183 ObjCPropertyDecl::PropertyAttributeKind Attr =
6184 PD->getPropertyAttributesAsWritten();
6185
6186#define SET_CXOBJCPROP_ATTR(A) \
6187 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6188 Result |= CXObjCPropertyAttr_##A
6189 SET_CXOBJCPROP_ATTR(readonly);
6190 SET_CXOBJCPROP_ATTR(getter);
6191 SET_CXOBJCPROP_ATTR(assign);
6192 SET_CXOBJCPROP_ATTR(readwrite);
6193 SET_CXOBJCPROP_ATTR(retain);
6194 SET_CXOBJCPROP_ATTR(copy);
6195 SET_CXOBJCPROP_ATTR(nonatomic);
6196 SET_CXOBJCPROP_ATTR(setter);
6197 SET_CXOBJCPROP_ATTR(atomic);
6198 SET_CXOBJCPROP_ATTR(weak);
6199 SET_CXOBJCPROP_ATTR(strong);
6200 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6201#undef SET_CXOBJCPROP_ATTR
6202
6203 return Result;
6204}
6205
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006206unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6207 if (!clang_isDeclaration(C.kind))
6208 return CXObjCDeclQualifier_None;
6209
6210 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6211 const Decl *D = getCursorDecl(C);
6212 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6213 QT = MD->getObjCDeclQualifier();
6214 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6215 QT = PD->getObjCDeclQualifier();
6216 if (QT == Decl::OBJC_TQ_None)
6217 return CXObjCDeclQualifier_None;
6218
6219 unsigned Result = CXObjCDeclQualifier_None;
6220 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6221 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6222 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6223 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6224 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6225 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6226
6227 return Result;
6228}
6229
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006230unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6231 if (!clang_isDeclaration(C.kind))
6232 return 0;
6233
6234 const Decl *D = getCursorDecl(C);
6235 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6236 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6237 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6238 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6239
6240 return 0;
6241}
6242
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006243unsigned clang_Cursor_isVariadic(CXCursor C) {
6244 if (!clang_isDeclaration(C.kind))
6245 return 0;
6246
6247 const Decl *D = getCursorDecl(C);
6248 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6249 return FD->isVariadic();
6250 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6251 return MD->isVariadic();
6252
6253 return 0;
6254}
6255
Guy Benyei11169dd2012-12-18 14:30:41 +00006256CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6257 if (!clang_isDeclaration(C.kind))
6258 return clang_getNullRange();
6259
6260 const Decl *D = getCursorDecl(C);
6261 ASTContext &Context = getCursorContext(C);
6262 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6263 if (!RC)
6264 return clang_getNullRange();
6265
6266 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6267}
6268
6269CXString clang_Cursor_getRawCommentText(CXCursor C) {
6270 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006271 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006272
6273 const Decl *D = getCursorDecl(C);
6274 ASTContext &Context = getCursorContext(C);
6275 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6276 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6277 StringRef();
6278
6279 // Don't duplicate the string because RawText points directly into source
6280 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006281 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006282}
6283
6284CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6285 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006286 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006287
6288 const Decl *D = getCursorDecl(C);
6289 const ASTContext &Context = getCursorContext(C);
6290 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6291
6292 if (RC) {
6293 StringRef BriefText = RC->getBriefText(Context);
6294
6295 // Don't duplicate the string because RawComment ensures that this memory
6296 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006297 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006298 }
6299
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006300 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006301}
6302
6303CXComment clang_Cursor_getParsedComment(CXCursor C) {
6304 if (!clang_isDeclaration(C.kind))
6305 return cxcomment::createCXComment(NULL, NULL);
6306
6307 const Decl *D = getCursorDecl(C);
6308 const ASTContext &Context = getCursorContext(C);
6309 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6310
6311 return cxcomment::createCXComment(FC, getCursorTU(C));
6312}
6313
6314CXModule clang_Cursor_getModule(CXCursor C) {
6315 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006316 if (const ImportDecl *ImportD =
6317 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006318 return ImportD->getImportedModule();
6319 }
6320
6321 return 0;
6322}
6323
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006324CXFile clang_Module_getASTFile(CXModule CXMod) {
6325 if (!CXMod)
6326 return 0;
6327 Module *Mod = static_cast<Module*>(CXMod);
6328 return const_cast<FileEntry *>(Mod->getASTFile());
6329}
6330
Guy Benyei11169dd2012-12-18 14:30:41 +00006331CXModule clang_Module_getParent(CXModule CXMod) {
6332 if (!CXMod)
6333 return 0;
6334 Module *Mod = static_cast<Module*>(CXMod);
6335 return Mod->Parent;
6336}
6337
6338CXString clang_Module_getName(CXModule CXMod) {
6339 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006340 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006341 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006342 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006343}
6344
6345CXString clang_Module_getFullName(CXModule CXMod) {
6346 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006347 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006348 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006349 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006350}
6351
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006352unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6353 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006354 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006355 LOG_BAD_TU(TU);
6356 return 0;
6357 }
6358 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006359 return 0;
6360 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006361 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6362 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6363 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006364}
6365
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006366CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6367 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006368 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006369 LOG_BAD_TU(TU);
6370 return 0;
6371 }
6372 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006373 return 0;
6374 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006375 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006376
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006377 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6378 if (Index < TopHeaders.size())
6379 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006380
6381 return 0;
6382}
6383
6384} // end: extern "C"
6385
6386//===----------------------------------------------------------------------===//
6387// C++ AST instrospection.
6388//===----------------------------------------------------------------------===//
6389
6390extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006391unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6392 if (!clang_isDeclaration(C.kind))
6393 return 0;
6394
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006395 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006396 const CXXMethodDecl *Method =
6397 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006398 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6399}
6400
Guy Benyei11169dd2012-12-18 14:30:41 +00006401unsigned clang_CXXMethod_isStatic(CXCursor C) {
6402 if (!clang_isDeclaration(C.kind))
6403 return 0;
6404
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006405 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006406 const CXXMethodDecl *Method =
6407 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006408 return (Method && Method->isStatic()) ? 1 : 0;
6409}
6410
6411unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6412 if (!clang_isDeclaration(C.kind))
6413 return 0;
6414
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006415 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006416 const CXXMethodDecl *Method =
6417 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006418 return (Method && Method->isVirtual()) ? 1 : 0;
6419}
6420} // end: extern "C"
6421
6422//===----------------------------------------------------------------------===//
6423// Attribute introspection.
6424//===----------------------------------------------------------------------===//
6425
6426extern "C" {
6427CXType clang_getIBOutletCollectionType(CXCursor C) {
6428 if (C.kind != CXCursor_IBOutletCollectionAttr)
6429 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6430
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006431 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006432 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6433
6434 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6435}
6436} // end: extern "C"
6437
6438//===----------------------------------------------------------------------===//
6439// Inspecting memory usage.
6440//===----------------------------------------------------------------------===//
6441
6442typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6443
6444static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6445 enum CXTUResourceUsageKind k,
6446 unsigned long amount) {
6447 CXTUResourceUsageEntry entry = { k, amount };
6448 entries.push_back(entry);
6449}
6450
6451extern "C" {
6452
6453const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6454 const char *str = "";
6455 switch (kind) {
6456 case CXTUResourceUsage_AST:
6457 str = "ASTContext: expressions, declarations, and types";
6458 break;
6459 case CXTUResourceUsage_Identifiers:
6460 str = "ASTContext: identifiers";
6461 break;
6462 case CXTUResourceUsage_Selectors:
6463 str = "ASTContext: selectors";
6464 break;
6465 case CXTUResourceUsage_GlobalCompletionResults:
6466 str = "Code completion: cached global results";
6467 break;
6468 case CXTUResourceUsage_SourceManagerContentCache:
6469 str = "SourceManager: content cache allocator";
6470 break;
6471 case CXTUResourceUsage_AST_SideTables:
6472 str = "ASTContext: side tables";
6473 break;
6474 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6475 str = "SourceManager: malloc'ed memory buffers";
6476 break;
6477 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6478 str = "SourceManager: mmap'ed memory buffers";
6479 break;
6480 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6481 str = "ExternalASTSource: malloc'ed memory buffers";
6482 break;
6483 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6484 str = "ExternalASTSource: mmap'ed memory buffers";
6485 break;
6486 case CXTUResourceUsage_Preprocessor:
6487 str = "Preprocessor: malloc'ed memory";
6488 break;
6489 case CXTUResourceUsage_PreprocessingRecord:
6490 str = "Preprocessor: PreprocessingRecord";
6491 break;
6492 case CXTUResourceUsage_SourceManager_DataStructures:
6493 str = "SourceManager: data structures and tables";
6494 break;
6495 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6496 str = "Preprocessor: header search tables";
6497 break;
6498 }
6499 return str;
6500}
6501
6502CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006503 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006504 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006505 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6506 return usage;
6507 }
6508
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006509 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006510 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6511 ASTContext &astContext = astUnit->getASTContext();
6512
6513 // How much memory is used by AST nodes and types?
6514 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6515 (unsigned long) astContext.getASTAllocatedMemory());
6516
6517 // How much memory is used by identifiers?
6518 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6519 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6520
6521 // How much memory is used for selectors?
6522 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6523 (unsigned long) astContext.Selectors.getTotalMemory());
6524
6525 // How much memory is used by ASTContext's side tables?
6526 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6527 (unsigned long) astContext.getSideTableAllocatedMemory());
6528
6529 // How much memory is used for caching global code completion results?
6530 unsigned long completionBytes = 0;
6531 if (GlobalCodeCompletionAllocator *completionAllocator =
6532 astUnit->getCachedCompletionAllocator().getPtr()) {
6533 completionBytes = completionAllocator->getTotalMemory();
6534 }
6535 createCXTUResourceUsageEntry(*entries,
6536 CXTUResourceUsage_GlobalCompletionResults,
6537 completionBytes);
6538
6539 // How much memory is being used by SourceManager's content cache?
6540 createCXTUResourceUsageEntry(*entries,
6541 CXTUResourceUsage_SourceManagerContentCache,
6542 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6543
6544 // How much memory is being used by the MemoryBuffer's in SourceManager?
6545 const SourceManager::MemoryBufferSizes &srcBufs =
6546 astUnit->getSourceManager().getMemoryBufferSizes();
6547
6548 createCXTUResourceUsageEntry(*entries,
6549 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6550 (unsigned long) srcBufs.malloc_bytes);
6551 createCXTUResourceUsageEntry(*entries,
6552 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6553 (unsigned long) srcBufs.mmap_bytes);
6554 createCXTUResourceUsageEntry(*entries,
6555 CXTUResourceUsage_SourceManager_DataStructures,
6556 (unsigned long) astContext.getSourceManager()
6557 .getDataStructureSizes());
6558
6559 // How much memory is being used by the ExternalASTSource?
6560 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6561 const ExternalASTSource::MemoryBufferSizes &sizes =
6562 esrc->getMemoryBufferSizes();
6563
6564 createCXTUResourceUsageEntry(*entries,
6565 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6566 (unsigned long) sizes.malloc_bytes);
6567 createCXTUResourceUsageEntry(*entries,
6568 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6569 (unsigned long) sizes.mmap_bytes);
6570 }
6571
6572 // How much memory is being used by the Preprocessor?
6573 Preprocessor &pp = astUnit->getPreprocessor();
6574 createCXTUResourceUsageEntry(*entries,
6575 CXTUResourceUsage_Preprocessor,
6576 pp.getTotalMemory());
6577
6578 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6579 createCXTUResourceUsageEntry(*entries,
6580 CXTUResourceUsage_PreprocessingRecord,
6581 pRec->getTotalMemory());
6582 }
6583
6584 createCXTUResourceUsageEntry(*entries,
6585 CXTUResourceUsage_Preprocessor_HeaderSearch,
6586 pp.getHeaderSearchInfo().getTotalMemory());
6587
6588 CXTUResourceUsage usage = { (void*) entries.get(),
6589 (unsigned) entries->size(),
6590 entries->size() ? &(*entries)[0] : 0 };
6591 entries.take();
6592 return usage;
6593}
6594
6595void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6596 if (usage.data)
6597 delete (MemUsageEntries*) usage.data;
6598}
6599
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006600CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6601 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006602 skipped->count = 0;
6603 skipped->ranges = 0;
6604
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006605 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006606 LOG_BAD_TU(TU);
6607 return skipped;
6608 }
6609
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006610 if (!file)
6611 return skipped;
6612
6613 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6614 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6615 if (!ppRec)
6616 return skipped;
6617
6618 ASTContext &Ctx = astUnit->getASTContext();
6619 SourceManager &sm = Ctx.getSourceManager();
6620 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6621 FileID wantedFileID = sm.translateFile(fileEntry);
6622
6623 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6624 std::vector<SourceRange> wantedRanges;
6625 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6626 i != ei; ++i) {
6627 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6628 wantedRanges.push_back(*i);
6629 }
6630
6631 skipped->count = wantedRanges.size();
6632 skipped->ranges = new CXSourceRange[skipped->count];
6633 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6634 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6635
6636 return skipped;
6637}
6638
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006639void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6640 if (ranges) {
6641 delete[] ranges->ranges;
6642 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006643 }
6644}
6645
Guy Benyei11169dd2012-12-18 14:30:41 +00006646} // end extern "C"
6647
6648void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6649 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6650 for (unsigned I = 0; I != Usage.numEntries; ++I)
6651 fprintf(stderr, " %s: %lu\n",
6652 clang_getTUResourceUsageName(Usage.entries[I].kind),
6653 Usage.entries[I].amount);
6654
6655 clang_disposeCXTUResourceUsage(Usage);
6656}
6657
6658//===----------------------------------------------------------------------===//
6659// Misc. utility functions.
6660//===----------------------------------------------------------------------===//
6661
6662/// Default to using an 8 MB stack size on "safety" threads.
6663static unsigned SafetyStackThreadSize = 8 << 20;
6664
6665namespace clang {
6666
6667bool RunSafely(llvm::CrashRecoveryContext &CRC,
6668 void (*Fn)(void*), void *UserData,
6669 unsigned Size) {
6670 if (!Size)
6671 Size = GetSafetyThreadStackSize();
6672 if (Size)
6673 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6674 return CRC.RunSafely(Fn, UserData);
6675}
6676
6677unsigned GetSafetyThreadStackSize() {
6678 return SafetyStackThreadSize;
6679}
6680
6681void SetSafetyThreadStackSize(unsigned Value) {
6682 SafetyStackThreadSize = Value;
6683}
6684
6685}
6686
6687void clang::setThreadBackgroundPriority() {
6688 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6689 return;
6690
6691 // FIXME: Move to llvm/Support and make it cross-platform.
6692#ifdef __APPLE__
6693 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6694#endif
6695}
6696
6697void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6698 if (!Unit)
6699 return;
6700
6701 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6702 DEnd = Unit->stored_diag_end();
6703 D != DEnd; ++D) {
6704 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6705 CXString Msg = clang_formatDiagnostic(&Diag,
6706 clang_defaultDiagnosticDisplayOptions());
6707 fprintf(stderr, "%s\n", clang_getCString(Msg));
6708 clang_disposeString(Msg);
6709 }
6710#ifdef LLVM_ON_WIN32
6711 // On Windows, force a flush, since there may be multiple copies of
6712 // stderr and stdout in the file system, all with different buffers
6713 // but writing to the same device.
6714 fflush(stderr);
6715#endif
6716}
6717
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006718MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6719 SourceLocation MacroDefLoc,
6720 CXTranslationUnit TU){
6721 if (MacroDefLoc.isInvalid() || !TU)
6722 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006723 if (!II.hadMacroDefinition())
6724 return 0;
6725
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006726 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006727 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006728 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006729 if (MD) {
6730 for (MacroDirective::DefInfo
6731 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6732 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6733 return Def.getMacroInfo();
6734 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006735 }
6736
6737 return 0;
6738}
6739
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006740const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6741 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006742 if (!MacroDef || !TU)
6743 return 0;
6744 const IdentifierInfo *II = MacroDef->getName();
6745 if (!II)
6746 return 0;
6747
6748 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6749}
6750
6751MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6752 const Token &Tok,
6753 CXTranslationUnit TU) {
6754 if (!MI || !TU)
6755 return 0;
6756 if (Tok.isNot(tok::raw_identifier))
6757 return 0;
6758
6759 if (MI->getNumTokens() == 0)
6760 return 0;
6761 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6762 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006763 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006764
6765 // Check that the token is inside the definition and not its argument list.
6766 SourceManager &SM = Unit->getSourceManager();
6767 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6768 return 0;
6769 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6770 return 0;
6771
6772 Preprocessor &PP = Unit->getPreprocessor();
6773 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6774 if (!PPRec)
6775 return 0;
6776
6777 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6778 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6779 if (!II.hadMacroDefinition())
6780 return 0;
6781
6782 // Check that the identifier is not one of the macro arguments.
6783 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6784 return 0;
6785
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006786 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6787 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006788 return 0;
6789
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006790 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006791}
6792
6793MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6794 SourceLocation Loc,
6795 CXTranslationUnit TU) {
6796 if (Loc.isInvalid() || !MI || !TU)
6797 return 0;
6798
6799 if (MI->getNumTokens() == 0)
6800 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006801 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006802 Preprocessor &PP = Unit->getPreprocessor();
6803 if (!PP.getPreprocessingRecord())
6804 return 0;
6805 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6806 Token Tok;
6807 if (PP.getRawToken(Loc, Tok))
6808 return 0;
6809
6810 return checkForMacroInMacroDefinition(MI, Tok, TU);
6811}
6812
Guy Benyei11169dd2012-12-18 14:30:41 +00006813extern "C" {
6814
6815CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006816 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006817}
6818
6819} // end: extern "C"
6820
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006821Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6822 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006823 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006824 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006825 if (Unit->isMainFileAST())
6826 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006827 return *this;
6828 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006829 } else {
6830 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006831 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006832 return *this;
6833}
6834
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006835Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6836 *this << FE->getName();
6837 return *this;
6838}
6839
6840Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6841 CXString cursorName = clang_getCursorDisplayName(cursor);
6842 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6843 clang_disposeString(cursorName);
6844 return *this;
6845}
6846
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006847Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6848 CXFile File;
6849 unsigned Line, Column;
6850 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6851 CXString FileName = clang_getFileName(File);
6852 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6853 clang_disposeString(FileName);
6854 return *this;
6855}
6856
6857Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6858 CXSourceLocation BLoc = clang_getRangeStart(range);
6859 CXSourceLocation ELoc = clang_getRangeEnd(range);
6860
6861 CXFile BFile;
6862 unsigned BLine, BColumn;
6863 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6864
6865 CXFile EFile;
6866 unsigned ELine, EColumn;
6867 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6868
6869 CXString BFileName = clang_getFileName(BFile);
6870 if (BFile == EFile) {
6871 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6872 BLine, BColumn, ELine, EColumn);
6873 } else {
6874 CXString EFileName = clang_getFileName(EFile);
6875 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6876 BLine, BColumn)
6877 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6878 ELine, EColumn);
6879 clang_disposeString(EFileName);
6880 }
6881 clang_disposeString(BFileName);
6882 return *this;
6883}
6884
6885Logger &cxindex::Logger::operator<<(CXString Str) {
6886 *this << clang_getCString(Str);
6887 return *this;
6888}
6889
6890Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6891 LogOS << Fmt;
6892 return *this;
6893}
6894
6895cxindex::Logger::~Logger() {
6896 LogOS.flush();
6897
6898 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6899
6900 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6901
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006902 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006903 OS << "[libclang:" << Name << ':';
6904
6905 // FIXME: Portability.
6906#if HAVE_PTHREAD_H && __APPLE__
6907 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6908 OS << tid << ':';
6909#endif
6910
6911 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6912 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6913 OS << Msg.str() << '\n';
6914
6915 if (Trace) {
6916 llvm::sys::PrintStackTrace(stderr);
6917 OS << "--------------------------------------------------\n";
6918 }
6919}