blob: babfc3adea875cd92915110059f3aa68b3e93605 [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
1942void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001943
1944template<typename T>
1945void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
1946 for (typename T::varlist_const_iterator I = Node->varlist_begin(),
1947 E = Node->varlist_end();
1948 I != E; ++I)
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001949 Visitor->AddStmt(*I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001950}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001951
1952void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001953 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001954}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001955void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1956 const OMPFirstprivateClause *C) {
1957 VisitOMPClauseList(C);
1958}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001959void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001960 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001961}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001962}
Alexey Bataev756c1962013-09-24 03:17:45 +00001963
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001964void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1965 unsigned size = WL.size();
1966 OMPClauseEnqueue Visitor(this);
1967 Visitor.Visit(S);
1968 if (size == WL.size())
1969 return;
1970 // Now reverse the entries we just added. This will match the DFS
1971 // ordering performed by the worklist.
1972 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1973 std::reverse(I, E);
1974}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001975void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001976 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1977}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001978void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001979 AddDecl(B->getBlockDecl());
1980}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001981void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001982 EnqueueChildren(E);
1983 AddTypeLoc(E->getTypeSourceInfo());
1984}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001985void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1986 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001987 E = S->body_rend(); I != E; ++I) {
1988 AddStmt(*I);
1989 }
1990}
1991void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001992VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001993 AddStmt(S->getSubStmt());
1994 AddDeclarationNameInfo(S);
1995 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1996 AddNestedNameSpecifierLoc(QualifierLoc);
1997}
1998
1999void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002000VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002001 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2002 AddDeclarationNameInfo(E);
2003 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2004 AddNestedNameSpecifierLoc(QualifierLoc);
2005 if (!E->isImplicitAccess())
2006 AddStmt(E->getBase());
2007}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002008void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002009 // Enqueue the initializer , if any.
2010 AddStmt(E->getInitializer());
2011 // Enqueue the array size, if any.
2012 AddStmt(E->getArraySize());
2013 // Enqueue the allocated type.
2014 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2015 // Enqueue the placement arguments.
2016 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2017 AddStmt(E->getPlacementArg(I-1));
2018}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002019void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002020 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2021 AddStmt(CE->getArg(I-1));
2022 AddStmt(CE->getCallee());
2023 AddStmt(CE->getArg(0));
2024}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002025void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2026 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002027 // Visit the name of the type being destroyed.
2028 AddTypeLoc(E->getDestroyedTypeInfo());
2029 // Visit the scope type that looks disturbingly like the nested-name-specifier
2030 // but isn't.
2031 AddTypeLoc(E->getScopeTypeInfo());
2032 // Visit the nested-name-specifier.
2033 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2034 AddNestedNameSpecifierLoc(QualifierLoc);
2035 // Visit base expression.
2036 AddStmt(E->getBase());
2037}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002038void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2039 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002040 AddTypeLoc(E->getTypeSourceInfo());
2041}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002042void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2043 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002044 EnqueueChildren(E);
2045 AddTypeLoc(E->getTypeSourceInfo());
2046}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002047void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002048 EnqueueChildren(E);
2049 if (E->isTypeOperand())
2050 AddTypeLoc(E->getTypeOperandSourceInfo());
2051}
2052
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002053void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2054 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002055 EnqueueChildren(E);
2056 AddTypeLoc(E->getTypeSourceInfo());
2057}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002058void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002059 EnqueueChildren(E);
2060 if (E->isTypeOperand())
2061 AddTypeLoc(E->getTypeOperandSourceInfo());
2062}
2063
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002064void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002065 EnqueueChildren(S);
2066 AddDecl(S->getExceptionDecl());
2067}
2068
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002069void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002070 if (DR->hasExplicitTemplateArgs()) {
2071 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2072 }
2073 WL.push_back(DeclRefExprParts(DR, Parent));
2074}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002075void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2076 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002077 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2078 AddDeclarationNameInfo(E);
2079 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2080}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002081void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002082 unsigned size = WL.size();
2083 bool isFirst = true;
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002084 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00002085 D != DEnd; ++D) {
2086 AddDecl(*D, isFirst);
2087 isFirst = false;
2088 }
2089 if (size == WL.size())
2090 return;
2091 // Now reverse the entries we just added. This will match the DFS
2092 // ordering performed by the worklist.
2093 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2094 std::reverse(I, E);
2095}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002096void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002097 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002098 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002099 D = E->designators_rbegin(), DEnd = E->designators_rend();
2100 D != DEnd; ++D) {
2101 if (D->isFieldDesignator()) {
2102 if (FieldDecl *Field = D->getField())
2103 AddMemberRef(Field, D->getFieldLoc());
2104 continue;
2105 }
2106 if (D->isArrayDesignator()) {
2107 AddStmt(E->getArrayIndex(*D));
2108 continue;
2109 }
2110 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2111 AddStmt(E->getArrayRangeEnd(*D));
2112 AddStmt(E->getArrayRangeStart(*D));
2113 }
2114}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002115void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002116 EnqueueChildren(E);
2117 AddTypeLoc(E->getTypeInfoAsWritten());
2118}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002119void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002120 AddStmt(FS->getBody());
2121 AddStmt(FS->getInc());
2122 AddStmt(FS->getCond());
2123 AddDecl(FS->getConditionVariable());
2124 AddStmt(FS->getInit());
2125}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002126void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002127 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2128}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002129void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002130 AddStmt(If->getElse());
2131 AddStmt(If->getThen());
2132 AddStmt(If->getCond());
2133 AddDecl(If->getConditionVariable());
2134}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002135void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002136 // We care about the syntactic form of the initializer list, only.
2137 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2138 IE = Syntactic;
2139 EnqueueChildren(IE);
2140}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002141void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002142 WL.push_back(MemberExprParts(M, Parent));
2143
2144 // If the base of the member access expression is an implicit 'this', don't
2145 // visit it.
2146 // FIXME: If we ever want to show these implicit accesses, this will be
2147 // unfortunate. However, clang_getCursor() relies on this behavior.
2148 if (!M->isImplicitAccess())
2149 AddStmt(M->getBase());
2150}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002151void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002152 AddTypeLoc(E->getEncodedTypeSourceInfo());
2153}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002154void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002155 EnqueueChildren(M);
2156 AddTypeLoc(M->getClassReceiverTypeInfo());
2157}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002158void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002159 // Visit the components of the offsetof expression.
2160 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2161 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2162 const OffsetOfNode &Node = E->getComponent(I-1);
2163 switch (Node.getKind()) {
2164 case OffsetOfNode::Array:
2165 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2166 break;
2167 case OffsetOfNode::Field:
2168 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2169 break;
2170 case OffsetOfNode::Identifier:
2171 case OffsetOfNode::Base:
2172 continue;
2173 }
2174 }
2175 // Visit the type into which we're computing the offset.
2176 AddTypeLoc(E->getTypeSourceInfo());
2177}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002178void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002179 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2180 WL.push_back(OverloadExprParts(E, Parent));
2181}
2182void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002183 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002184 EnqueueChildren(E);
2185 if (E->isArgumentType())
2186 AddTypeLoc(E->getArgumentTypeInfo());
2187}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002188void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002189 EnqueueChildren(S);
2190}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002191void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002192 AddStmt(S->getBody());
2193 AddStmt(S->getCond());
2194 AddDecl(S->getConditionVariable());
2195}
2196
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002197void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002198 AddStmt(W->getBody());
2199 AddStmt(W->getCond());
2200 AddDecl(W->getConditionVariable());
2201}
2202
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002203void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002204 for (unsigned I = E->getNumArgs(); I > 0; --I)
2205 AddTypeLoc(E->getArg(I-1));
2206}
2207
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002208void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002209 AddTypeLoc(E->getQueriedTypeSourceInfo());
2210}
2211
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002212void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002213 EnqueueChildren(E);
2214}
2215
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002216void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002217 VisitOverloadExpr(U);
2218 if (!U->isImplicitAccess())
2219 AddStmt(U->getBase());
2220}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002221void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002222 AddStmt(E->getSubExpr());
2223 AddTypeLoc(E->getWrittenTypeInfo());
2224}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002225void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002226 WL.push_back(SizeOfPackExprParts(E, Parent));
2227}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002228void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002229 // If the opaque value has a source expression, just transparently
2230 // visit that. This is useful for (e.g.) pseudo-object expressions.
2231 if (Expr *SourceExpr = E->getSourceExpr())
2232 return Visit(SourceExpr);
2233}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002234void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002235 AddStmt(E->getBody());
2236 WL.push_back(LambdaExprParts(E, Parent));
2237}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002238void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002239 // Treat the expression like its syntactic form.
2240 Visit(E->getSyntacticForm());
2241}
2242
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002243void EnqueueVisitor::VisitOMPExecutableDirective(
2244 const OMPExecutableDirective *D) {
2245 EnqueueChildren(D);
2246 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2247 E = D->clauses().end();
2248 I != E; ++I)
2249 EnqueueChildren(*I);
2250}
2251
2252void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2253 VisitOMPExecutableDirective(D);
2254}
2255
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002256void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002257 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2258}
2259
2260bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2261 if (RegionOfInterest.isValid()) {
2262 SourceRange Range = getRawCursorExtent(C);
2263 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2264 return false;
2265 }
2266 return true;
2267}
2268
2269bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2270 while (!WL.empty()) {
2271 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002272 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002273
2274 // Set the Parent field, then back to its old value once we're done.
2275 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2276
2277 switch (LI.getKind()) {
2278 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002279 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002280 if (!D)
2281 continue;
2282
2283 // For now, perform default visitation for Decls.
2284 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2285 cast<DeclVisit>(&LI)->isFirst())))
2286 return true;
2287
2288 continue;
2289 }
2290 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2291 const ASTTemplateArgumentListInfo *ArgList =
2292 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2293 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2294 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2295 Arg != ArgEnd; ++Arg) {
2296 if (VisitTemplateArgumentLoc(*Arg))
2297 return true;
2298 }
2299 continue;
2300 }
2301 case VisitorJob::TypeLocVisitKind: {
2302 // Perform default visitation for TypeLocs.
2303 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2304 return true;
2305 continue;
2306 }
2307 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002308 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002309 if (LabelStmt *stmt = LS->getStmt()) {
2310 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2311 TU))) {
2312 return true;
2313 }
2314 }
2315 continue;
2316 }
2317
2318 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2319 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2320 if (VisitNestedNameSpecifierLoc(V->get()))
2321 return true;
2322 continue;
2323 }
2324
2325 case VisitorJob::DeclarationNameInfoVisitKind: {
2326 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2327 ->get()))
2328 return true;
2329 continue;
2330 }
2331 case VisitorJob::MemberRefVisitKind: {
2332 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2333 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2334 return true;
2335 continue;
2336 }
2337 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002338 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002339 if (!S)
2340 continue;
2341
2342 // Update the current cursor.
2343 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2344 if (!IsInRegionOfInterest(Cursor))
2345 continue;
2346 switch (Visitor(Cursor, Parent, ClientData)) {
2347 case CXChildVisit_Break: return true;
2348 case CXChildVisit_Continue: break;
2349 case CXChildVisit_Recurse:
2350 if (PostChildrenVisitor)
2351 WL.push_back(PostChildrenVisit(0, Cursor));
2352 EnqueueWorkList(WL, S);
2353 break;
2354 }
2355 continue;
2356 }
2357 case VisitorJob::MemberExprPartsKind: {
2358 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002359 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002360
2361 // Visit the nested-name-specifier
2362 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2363 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2364 return true;
2365
2366 // Visit the declaration name.
2367 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2368 return true;
2369
2370 // Visit the explicitly-specified template arguments, if any.
2371 if (M->hasExplicitTemplateArgs()) {
2372 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2373 *ArgEnd = Arg + M->getNumTemplateArgs();
2374 Arg != ArgEnd; ++Arg) {
2375 if (VisitTemplateArgumentLoc(*Arg))
2376 return true;
2377 }
2378 }
2379 continue;
2380 }
2381 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002382 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002383 // Visit nested-name-specifier, if present.
2384 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2385 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2386 return true;
2387 // Visit declaration name.
2388 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2389 return true;
2390 continue;
2391 }
2392 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002393 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002394 // Visit the nested-name-specifier.
2395 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2396 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2397 return true;
2398 // Visit the declaration name.
2399 if (VisitDeclarationNameInfo(O->getNameInfo()))
2400 return true;
2401 // Visit the overloaded declaration reference.
2402 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2403 return true;
2404 continue;
2405 }
2406 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002407 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002408 NamedDecl *Pack = E->getPack();
2409 if (isa<TemplateTypeParmDecl>(Pack)) {
2410 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2411 E->getPackLoc(), TU)))
2412 return true;
2413
2414 continue;
2415 }
2416
2417 if (isa<TemplateTemplateParmDecl>(Pack)) {
2418 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2419 E->getPackLoc(), TU)))
2420 return true;
2421
2422 continue;
2423 }
2424
2425 // Non-type template parameter packs and function parameter packs are
2426 // treated like DeclRefExpr cursors.
2427 continue;
2428 }
2429
2430 case VisitorJob::LambdaExprPartsKind: {
2431 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002432 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002433 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2434 CEnd = E->explicit_capture_end();
2435 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002436 // FIXME: Lambda init-captures.
2437 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002438 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002439
Guy Benyei11169dd2012-12-18 14:30:41 +00002440 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2441 C->getLocation(),
2442 TU)))
2443 return true;
2444 }
2445
2446 // Visit parameters and return type, if present.
2447 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2448 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2449 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2450 // Visit the whole type.
2451 if (Visit(TL))
2452 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002453 } else if (FunctionProtoTypeLoc Proto =
2454 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002455 if (E->hasExplicitParameters()) {
2456 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002457 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2458 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002459 return true;
2460 } else {
2461 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002462 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002463 return true;
2464 }
2465 }
2466 }
2467 break;
2468 }
2469
2470 case VisitorJob::PostChildrenVisitKind:
2471 if (PostChildrenVisitor(Parent, ClientData))
2472 return true;
2473 break;
2474 }
2475 }
2476 return false;
2477}
2478
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002479bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002480 VisitorWorkList *WL = 0;
2481 if (!WorkListFreeList.empty()) {
2482 WL = WorkListFreeList.back();
2483 WL->clear();
2484 WorkListFreeList.pop_back();
2485 }
2486 else {
2487 WL = new VisitorWorkList();
2488 WorkListCache.push_back(WL);
2489 }
2490 EnqueueWorkList(*WL, S);
2491 bool result = RunVisitorWorkList(*WL);
2492 WorkListFreeList.push_back(WL);
2493 return result;
2494}
2495
2496namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002497typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002498RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2499 const DeclarationNameInfo &NI,
2500 const SourceRange &QLoc,
2501 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2502 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2503 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2504 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2505
2506 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2507
2508 RefNamePieces Pieces;
2509
2510 if (WantQualifier && QLoc.isValid())
2511 Pieces.push_back(QLoc);
2512
2513 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2514 Pieces.push_back(NI.getLoc());
2515
2516 if (WantTemplateArgs && TemplateArgs)
2517 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2518 TemplateArgs->RAngleLoc));
2519
2520 if (Kind == DeclarationName::CXXOperatorName) {
2521 Pieces.push_back(SourceLocation::getFromRawEncoding(
2522 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2523 Pieces.push_back(SourceLocation::getFromRawEncoding(
2524 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2525 }
2526
2527 if (WantSinglePiece) {
2528 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2529 Pieces.clear();
2530 Pieces.push_back(R);
2531 }
2532
2533 return Pieces;
2534}
2535}
2536
2537//===----------------------------------------------------------------------===//
2538// Misc. API hooks.
2539//===----------------------------------------------------------------------===//
2540
2541static llvm::sys::Mutex EnableMultithreadingMutex;
2542static bool EnabledMultithreading;
2543
Chad Rosier05c71aa2013-03-27 18:28:23 +00002544static void fatal_error_handler(void *user_data, const std::string& reason,
2545 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002546 // Write the result out to stderr avoiding errs() because raw_ostreams can
2547 // call report_fatal_error.
2548 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2549 ::abort();
2550}
2551
2552extern "C" {
2553CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2554 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002555 // We use crash recovery to make some of our APIs more reliable, implicitly
2556 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002557 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2558 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002559
2560 // Enable support for multithreading in LLVM.
2561 {
2562 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2563 if (!EnabledMultithreading) {
2564 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2565 llvm::llvm_start_multithreaded();
2566 EnabledMultithreading = true;
2567 }
2568 }
2569
2570 CIndexer *CIdxr = new CIndexer();
2571 if (excludeDeclarationsFromPCH)
2572 CIdxr->setOnlyLocalDecls();
2573 if (displayDiagnostics)
2574 CIdxr->setDisplayDiagnostics();
2575
2576 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2577 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2578 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2579 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2580 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2581 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2582
2583 return CIdxr;
2584}
2585
2586void clang_disposeIndex(CXIndex CIdx) {
2587 if (CIdx)
2588 delete static_cast<CIndexer *>(CIdx);
2589}
2590
2591void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2592 if (CIdx)
2593 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2594}
2595
2596unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2597 if (CIdx)
2598 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2599 return 0;
2600}
2601
2602void clang_toggleCrashRecovery(unsigned isEnabled) {
2603 if (isEnabled)
2604 llvm::CrashRecoveryContext::Enable();
2605 else
2606 llvm::CrashRecoveryContext::Disable();
2607}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002608
Guy Benyei11169dd2012-12-18 14:30:41 +00002609CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2610 const char *ast_filename) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002611 CXTranslationUnit TU;
2612 enum CXErrorCode Result =
2613 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002614 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002615 assert((TU && Result == CXError_Success) ||
2616 (!TU && Result != CXError_Success));
2617 return TU;
2618}
2619
2620enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2621 const char *ast_filename,
2622 CXTranslationUnit *out_TU) {
2623 if (!CIdx || !ast_filename || !out_TU)
2624 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002625
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002626 LOG_FUNC_SECTION {
2627 *Log << ast_filename;
2628 }
2629
Guy Benyei11169dd2012-12-18 14:30:41 +00002630 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2631 FileSystemOptions FileSystemOpts;
2632
2633 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002634 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002635 CXXIdx->getOnlyLocalDecls(), None,
2636 /*CaptureDiagnostics=*/true,
2637 /*AllowPCHWithCompilerErrors=*/true,
2638 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002639 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2640 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002641}
2642
2643unsigned clang_defaultEditingTranslationUnitOptions() {
2644 return CXTranslationUnit_PrecompiledPreamble |
2645 CXTranslationUnit_CacheCompletionResults;
2646}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002647
Guy Benyei11169dd2012-12-18 14:30:41 +00002648CXTranslationUnit
2649clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2650 const char *source_filename,
2651 int num_command_line_args,
2652 const char * const *command_line_args,
2653 unsigned num_unsaved_files,
2654 struct CXUnsavedFile *unsaved_files) {
2655 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2656 return clang_parseTranslationUnit(CIdx, source_filename,
2657 command_line_args, num_command_line_args,
2658 unsaved_files, num_unsaved_files,
2659 Options);
2660}
2661
2662struct ParseTranslationUnitInfo {
2663 CXIndex CIdx;
2664 const char *source_filename;
2665 const char *const *command_line_args;
2666 int num_command_line_args;
2667 struct CXUnsavedFile *unsaved_files;
2668 unsigned num_unsaved_files;
2669 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002670 CXTranslationUnit *out_TU;
2671 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002672};
2673static void clang_parseTranslationUnit_Impl(void *UserData) {
2674 ParseTranslationUnitInfo *PTUI =
2675 static_cast<ParseTranslationUnitInfo*>(UserData);
2676 CXIndex CIdx = PTUI->CIdx;
2677 const char *source_filename = PTUI->source_filename;
2678 const char * const *command_line_args = PTUI->command_line_args;
2679 int num_command_line_args = PTUI->num_command_line_args;
2680 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2681 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2682 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002683 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002684
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002685 // Check arguments.
2686 if (!CIdx || !out_TU ||
2687 (unsaved_files == NULL && num_unsaved_files != 0)) {
2688 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002689 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002690 }
2691
2692 // Set up the initial return values.
2693 *out_TU = NULL;
2694 PTUI->result = CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002695
2696 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2697
2698 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2699 setThreadBackgroundPriority();
2700
2701 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2702 // FIXME: Add a flag for modules.
2703 TranslationUnitKind TUKind
2704 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002705 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002706 = options & CXTranslationUnit_CacheCompletionResults;
2707 bool IncludeBriefCommentsInCodeCompletion
2708 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2709 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2710 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2711
2712 // Configure the diagnostics.
2713 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002714 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002715
2716 // Recover resources if we crash before exiting this function.
2717 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2718 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2719 DiagCleanup(Diags.getPtr());
2720
2721 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2722 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2723
2724 // Recover resources if we crash before exiting this function.
2725 llvm::CrashRecoveryContextCleanupRegistrar<
2726 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2727
2728 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2729 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2730 const llvm::MemoryBuffer *Buffer
2731 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2732 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2733 Buffer));
2734 }
2735
2736 OwningPtr<std::vector<const char *> >
2737 Args(new std::vector<const char*>());
2738
2739 // Recover resources if we crash before exiting this method.
2740 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2741 ArgsCleanup(Args.get());
2742
2743 // Since the Clang C library is primarily used by batch tools dealing with
2744 // (often very broken) source code, where spell-checking can have a
2745 // significant negative impact on performance (particularly when
2746 // precompiled headers are involved), we disable it by default.
2747 // Only do this if we haven't found a spell-checking-related argument.
2748 bool FoundSpellCheckingArgument = false;
2749 for (int I = 0; I != num_command_line_args; ++I) {
2750 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2751 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2752 FoundSpellCheckingArgument = true;
2753 break;
2754 }
2755 }
2756 if (!FoundSpellCheckingArgument)
2757 Args->push_back("-fno-spell-checking");
2758
2759 Args->insert(Args->end(), command_line_args,
2760 command_line_args + num_command_line_args);
2761
2762 // The 'source_filename' argument is optional. If the caller does not
2763 // specify it then it is assumed that the source file is specified
2764 // in the actual argument list.
2765 // Put the source file after command_line_args otherwise if '-x' flag is
2766 // present it will be unused.
2767 if (source_filename)
2768 Args->push_back(source_filename);
2769
2770 // Do we need the detailed preprocessing record?
2771 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2772 Args->push_back("-Xclang");
2773 Args->push_back("-detailed-preprocessing-record");
2774 }
2775
2776 unsigned NumErrors = Diags->getClient()->getNumErrors();
2777 OwningPtr<ASTUnit> ErrUnit;
2778 OwningPtr<ASTUnit> Unit(
2779 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2780 /* vector::data() not portable */,
2781 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2782 Diags,
2783 CXXIdx->getClangResourcesPath(),
2784 CXXIdx->getOnlyLocalDecls(),
2785 /*CaptureDiagnostics=*/true,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002786 *RemappedFiles.get(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002787 /*RemappedFilesKeepOriginalName=*/true,
2788 PrecompilePreamble,
2789 TUKind,
Alp Toker8c8a8752013-12-03 06:53:35 +00002790 CacheCodeCompletionResults,
Guy Benyei11169dd2012-12-18 14:30:41 +00002791 IncludeBriefCommentsInCodeCompletion,
2792 /*AllowPCHWithCompilerErrors=*/true,
2793 SkipFunctionBodies,
2794 /*UserFilesAreVolatile=*/true,
2795 ForSerialization,
2796 &ErrUnit));
2797
2798 if (NumErrors != Diags->getClient()->getNumErrors()) {
2799 // Make sure to check that 'Unit' is non-NULL.
2800 if (CXXIdx->getDisplayDiagnostics())
2801 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2802 }
2803
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002804 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2805 PTUI->result = CXError_ASTReadError;
2806 } else {
2807 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.take());
2808 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2809 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002810}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002811
2812CXTranslationUnit
2813clang_parseTranslationUnit(CXIndex CIdx,
2814 const char *source_filename,
2815 const char *const *command_line_args,
2816 int num_command_line_args,
2817 struct CXUnsavedFile *unsaved_files,
2818 unsigned num_unsaved_files,
2819 unsigned options) {
2820 CXTranslationUnit TU;
2821 enum CXErrorCode Result = clang_parseTranslationUnit2(
2822 CIdx, source_filename, command_line_args, num_command_line_args,
2823 unsaved_files, num_unsaved_files, options, &TU);
2824 assert((TU && Result == CXError_Success) ||
2825 (!TU && Result != CXError_Success));
2826 return TU;
2827}
2828
2829enum CXErrorCode clang_parseTranslationUnit2(
2830 CXIndex CIdx,
2831 const char *source_filename,
2832 const char *const *command_line_args,
2833 int num_command_line_args,
2834 struct CXUnsavedFile *unsaved_files,
2835 unsigned num_unsaved_files,
2836 unsigned options,
2837 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002838 LOG_FUNC_SECTION {
2839 *Log << source_filename << ": ";
2840 for (int i = 0; i != num_command_line_args; ++i)
2841 *Log << command_line_args[i] << " ";
2842 }
2843
Guy Benyei11169dd2012-12-18 14:30:41 +00002844 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2845 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002846 num_unsaved_files, options, out_TU,
2847 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002848 llvm::CrashRecoveryContext CRC;
2849
2850 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2851 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2852 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2853 fprintf(stderr, " 'command_line_args' : [");
2854 for (int i = 0; i != num_command_line_args; ++i) {
2855 if (i)
2856 fprintf(stderr, ", ");
2857 fprintf(stderr, "'%s'", command_line_args[i]);
2858 }
2859 fprintf(stderr, "],\n");
2860 fprintf(stderr, " 'unsaved_files' : [");
2861 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2862 if (i)
2863 fprintf(stderr, ", ");
2864 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2865 unsaved_files[i].Length);
2866 }
2867 fprintf(stderr, "],\n");
2868 fprintf(stderr, " 'options' : %d,\n", options);
2869 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002870
2871 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002872 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002873 if (CXTranslationUnit *TU = PTUI.out_TU)
2874 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002875 }
2876
2877 return PTUI.result;
2878}
2879
2880unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2881 return CXSaveTranslationUnit_None;
2882}
2883
2884namespace {
2885
2886struct SaveTranslationUnitInfo {
2887 CXTranslationUnit TU;
2888 const char *FileName;
2889 unsigned options;
2890 CXSaveError result;
2891};
2892
2893}
2894
2895static void clang_saveTranslationUnit_Impl(void *UserData) {
2896 SaveTranslationUnitInfo *STUI =
2897 static_cast<SaveTranslationUnitInfo*>(UserData);
2898
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002899 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002900 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2901 setThreadBackgroundPriority();
2902
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002903 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002904 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2905}
2906
2907int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2908 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002909 LOG_FUNC_SECTION {
2910 *Log << TU << ' ' << FileName;
2911 }
2912
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002913 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002914 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002915 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002916 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002917
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002918 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002919 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2920 if (!CXXUnit->hasSema())
2921 return CXSaveError_InvalidTU;
2922
2923 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2924
2925 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2926 getenv("LIBCLANG_NOTHREADS")) {
2927 clang_saveTranslationUnit_Impl(&STUI);
2928
2929 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2930 PrintLibclangResourceUsage(TU);
2931
2932 return STUI.result;
2933 }
2934
2935 // We have an AST that has invalid nodes due to compiler errors.
2936 // Use a crash recovery thread for protection.
2937
2938 llvm::CrashRecoveryContext CRC;
2939
2940 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2941 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2942 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2943 fprintf(stderr, " 'options' : %d,\n", options);
2944 fprintf(stderr, "}\n");
2945
2946 return CXSaveError_Unknown;
2947
2948 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2949 PrintLibclangResourceUsage(TU);
2950 }
2951
2952 return STUI.result;
2953}
2954
2955void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2956 if (CTUnit) {
2957 // If the translation unit has been marked as unsafe to free, just discard
2958 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002959 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2960 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002961 return;
2962
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002963 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002964 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002965 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2966 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002967 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002968 delete CTUnit;
2969 }
2970}
2971
2972unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2973 return CXReparse_None;
2974}
2975
2976struct ReparseTranslationUnitInfo {
2977 CXTranslationUnit TU;
2978 unsigned num_unsaved_files;
2979 struct CXUnsavedFile *unsaved_files;
2980 unsigned options;
2981 int result;
2982};
2983
2984static void clang_reparseTranslationUnit_Impl(void *UserData) {
2985 ReparseTranslationUnitInfo *RTUI =
2986 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002987 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002988
Guy Benyei11169dd2012-12-18 14:30:41 +00002989 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002990 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2991 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2992 unsigned options = RTUI->options;
2993 (void) options;
2994
2995 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002996 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002997 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002998 RTUI->result = CXError_InvalidArguments;
2999 return;
3000 }
3001 if (unsaved_files == NULL && num_unsaved_files != 0) {
3002 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003003 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003004 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003005
3006 // Reset the associated diagnostics.
3007 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3008 TU->Diagnostics = 0;
3009
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003010 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003011 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3012 setThreadBackgroundPriority();
3013
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003014 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003015 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3016
3017 OwningPtr<std::vector<ASTUnit::RemappedFile> >
3018 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
3019
3020 // Recover resources if we crash before exiting this function.
3021 llvm::CrashRecoveryContextCleanupRegistrar<
3022 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3023
3024 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3025 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3026 const llvm::MemoryBuffer *Buffer
3027 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3028 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3029 Buffer));
3030 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003031
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003032 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003033 RTUI->result = CXError_Success;
3034 else if (isASTReadError(CXXUnit))
3035 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003036}
3037
3038int clang_reparseTranslationUnit(CXTranslationUnit TU,
3039 unsigned num_unsaved_files,
3040 struct CXUnsavedFile *unsaved_files,
3041 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003042 LOG_FUNC_SECTION {
3043 *Log << TU;
3044 }
3045
Guy Benyei11169dd2012-12-18 14:30:41 +00003046 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003047 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003048
3049 if (getenv("LIBCLANG_NOTHREADS")) {
3050 clang_reparseTranslationUnit_Impl(&RTUI);
3051 return RTUI.result;
3052 }
3053
3054 llvm::CrashRecoveryContext CRC;
3055
3056 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3057 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003058 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003059 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003060 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3061 PrintLibclangResourceUsage(TU);
3062
3063 return RTUI.result;
3064}
3065
3066
3067CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003068 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003069 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003070 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003071 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003072
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003073 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003074 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003075}
3076
3077CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003078 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003079 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003080 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003081 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003082
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003083 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003084 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3085}
3086
3087} // end: extern "C"
3088
3089//===----------------------------------------------------------------------===//
3090// CXFile Operations.
3091//===----------------------------------------------------------------------===//
3092
3093extern "C" {
3094CXString clang_getFileName(CXFile SFile) {
3095 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003096 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003097
3098 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003099 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003100}
3101
3102time_t clang_getFileTime(CXFile SFile) {
3103 if (!SFile)
3104 return 0;
3105
3106 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3107 return FEnt->getModificationTime();
3108}
3109
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003110CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003111 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003112 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003113 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003114 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003115
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003116 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003117
3118 FileManager &FMgr = CXXUnit->getFileManager();
3119 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3120}
3121
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003122unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3123 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003124 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003125 LOG_BAD_TU(TU);
3126 return 0;
3127 }
3128
3129 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003130 return 0;
3131
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003132 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003133 FileEntry *FEnt = static_cast<FileEntry *>(file);
3134 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3135 .isFileMultipleIncludeGuarded(FEnt);
3136}
3137
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003138int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3139 if (!file || !outID)
3140 return 1;
3141
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003142 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003143 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3144 outID->data[0] = ID.getDevice();
3145 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003146 outID->data[2] = FEnt->getModificationTime();
3147 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003148}
3149
Guy Benyei11169dd2012-12-18 14:30:41 +00003150} // end: extern "C"
3151
3152//===----------------------------------------------------------------------===//
3153// CXCursor Operations.
3154//===----------------------------------------------------------------------===//
3155
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003156static const Decl *getDeclFromExpr(const Stmt *E) {
3157 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003158 return getDeclFromExpr(CE->getSubExpr());
3159
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003160 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003161 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003162 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003163 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003164 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003165 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003166 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003167 if (PRE->isExplicitProperty())
3168 return PRE->getExplicitProperty();
3169 // It could be messaging both getter and setter as in:
3170 // ++myobj.myprop;
3171 // in which case prefer to associate the setter since it is less obvious
3172 // from inspecting the source that the setter is going to get called.
3173 if (PRE->isMessagingSetter())
3174 return PRE->getImplicitPropertySetter();
3175 return PRE->getImplicitPropertyGetter();
3176 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003177 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003178 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003179 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003180 if (Expr *Src = OVE->getSourceExpr())
3181 return getDeclFromExpr(Src);
3182
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003183 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003184 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003185 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003186 if (!CE->isElidable())
3187 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003188 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003189 return OME->getMethodDecl();
3190
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003191 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003192 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003193 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003194 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3195 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003196 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003197 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3198 isa<ParmVarDecl>(SizeOfPack->getPack()))
3199 return SizeOfPack->getPack();
3200
3201 return 0;
3202}
3203
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003204static SourceLocation getLocationFromExpr(const Expr *E) {
3205 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003206 return getLocationFromExpr(CE->getSubExpr());
3207
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003208 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003209 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003210 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003211 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003212 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003213 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003214 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003215 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003216 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003217 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003218 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003219 return PropRef->getLocation();
3220
3221 return E->getLocStart();
3222}
3223
3224extern "C" {
3225
3226unsigned clang_visitChildren(CXCursor parent,
3227 CXCursorVisitor visitor,
3228 CXClientData client_data) {
3229 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3230 /*VisitPreprocessorLast=*/false);
3231 return CursorVis.VisitChildren(parent);
3232}
3233
3234#ifndef __has_feature
3235#define __has_feature(x) 0
3236#endif
3237#if __has_feature(blocks)
3238typedef enum CXChildVisitResult
3239 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3240
3241static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3242 CXClientData client_data) {
3243 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3244 return block(cursor, parent);
3245}
3246#else
3247// If we are compiled with a compiler that doesn't have native blocks support,
3248// define and call the block manually, so the
3249typedef struct _CXChildVisitResult
3250{
3251 void *isa;
3252 int flags;
3253 int reserved;
3254 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3255 CXCursor);
3256} *CXCursorVisitorBlock;
3257
3258static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3259 CXClientData client_data) {
3260 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3261 return block->invoke(block, cursor, parent);
3262}
3263#endif
3264
3265
3266unsigned clang_visitChildrenWithBlock(CXCursor parent,
3267 CXCursorVisitorBlock block) {
3268 return clang_visitChildren(parent, visitWithBlock, block);
3269}
3270
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003271static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003272 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003273 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003274
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003275 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003276 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003277 if (const ObjCPropertyImplDecl *PropImpl =
3278 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003279 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003280 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003281
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003282 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003283 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003284 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003285
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003286 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003287 }
3288
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003289 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003290 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003291
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003292 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003293 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3294 // and returns different names. NamedDecl returns the class name and
3295 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003296 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003297
3298 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003299 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003300
3301 SmallString<1024> S;
3302 llvm::raw_svector_ostream os(S);
3303 ND->printName(os);
3304
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003305 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003306}
3307
3308CXString clang_getCursorSpelling(CXCursor C) {
3309 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003310 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003311
3312 if (clang_isReference(C.kind)) {
3313 switch (C.kind) {
3314 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003315 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003316 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003317 }
3318 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003319 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003320 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003321 }
3322 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003323 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003324 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003325 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003326 }
3327 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003328 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003329 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003330 }
3331 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003332 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003333 assert(Type && "Missing type decl");
3334
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003335 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003336 getAsString());
3337 }
3338 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003339 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003340 assert(Template && "Missing template decl");
3341
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003342 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003343 }
3344
3345 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003346 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003347 assert(NS && "Missing namespace decl");
3348
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003349 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003350 }
3351
3352 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003353 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003354 assert(Field && "Missing member decl");
3355
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003356 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003357 }
3358
3359 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003360 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003361 assert(Label && "Missing label");
3362
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003363 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003364 }
3365
3366 case CXCursor_OverloadedDeclRef: {
3367 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003368 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3369 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003370 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003371 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003372 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003373 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003374 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003375 OverloadedTemplateStorage *Ovl
3376 = Storage.get<OverloadedTemplateStorage*>();
3377 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003378 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003379 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 }
3381
3382 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003383 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 assert(Var && "Missing variable decl");
3385
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003386 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003387 }
3388
3389 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003390 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003391 }
3392 }
3393
3394 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003395 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003396 if (D)
3397 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003398 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003399 }
3400
3401 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003402 const Stmt *S = getCursorStmt(C);
3403 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003404 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003405
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003406 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003407 }
3408
3409 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003410 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003411 ->getNameStart());
3412
3413 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003414 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003415 ->getNameStart());
3416
3417 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003418 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003419
3420 if (clang_isDeclaration(C.kind))
3421 return getDeclSpelling(getCursorDecl(C));
3422
3423 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003424 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003425 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003426 }
3427
3428 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003429 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003430 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003431 }
3432
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003433 if (C.kind == CXCursor_PackedAttr) {
3434 return cxstring::createRef("packed");
3435 }
3436
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003437 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003438}
3439
3440CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3441 unsigned pieceIndex,
3442 unsigned options) {
3443 if (clang_Cursor_isNull(C))
3444 return clang_getNullRange();
3445
3446 ASTContext &Ctx = getCursorContext(C);
3447
3448 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003449 const Stmt *S = getCursorStmt(C);
3450 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003451 if (pieceIndex > 0)
3452 return clang_getNullRange();
3453 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3454 }
3455
3456 return clang_getNullRange();
3457 }
3458
3459 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003460 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003461 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3462 if (pieceIndex >= ME->getNumSelectorLocs())
3463 return clang_getNullRange();
3464 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3465 }
3466 }
3467
3468 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3469 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003470 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003471 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3472 if (pieceIndex >= MD->getNumSelectorLocs())
3473 return clang_getNullRange();
3474 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3475 }
3476 }
3477
3478 if (C.kind == CXCursor_ObjCCategoryDecl ||
3479 C.kind == CXCursor_ObjCCategoryImplDecl) {
3480 if (pieceIndex > 0)
3481 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003482 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003483 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3484 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003485 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003486 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3487 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3488 }
3489
3490 if (C.kind == CXCursor_ModuleImportDecl) {
3491 if (pieceIndex > 0)
3492 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003493 if (const ImportDecl *ImportD =
3494 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003495 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3496 if (!Locs.empty())
3497 return cxloc::translateSourceRange(Ctx,
3498 SourceRange(Locs.front(), Locs.back()));
3499 }
3500 return clang_getNullRange();
3501 }
3502
3503 // FIXME: A CXCursor_InclusionDirective should give the location of the
3504 // filename, but we don't keep track of this.
3505
3506 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3507 // but we don't keep track of this.
3508
3509 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3510 // but we don't keep track of this.
3511
3512 // Default handling, give the location of the cursor.
3513
3514 if (pieceIndex > 0)
3515 return clang_getNullRange();
3516
3517 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3518 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3519 return cxloc::translateSourceRange(Ctx, Loc);
3520}
3521
3522CXString clang_getCursorDisplayName(CXCursor C) {
3523 if (!clang_isDeclaration(C.kind))
3524 return clang_getCursorSpelling(C);
3525
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003526 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003527 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003528 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003529
3530 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003531 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003532 D = FunTmpl->getTemplatedDecl();
3533
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003534 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003535 SmallString<64> Str;
3536 llvm::raw_svector_ostream OS(Str);
3537 OS << *Function;
3538 if (Function->getPrimaryTemplate())
3539 OS << "<>";
3540 OS << "(";
3541 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3542 if (I)
3543 OS << ", ";
3544 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3545 }
3546
3547 if (Function->isVariadic()) {
3548 if (Function->getNumParams())
3549 OS << ", ";
3550 OS << "...";
3551 }
3552 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003553 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003554 }
3555
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003556 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003557 SmallString<64> Str;
3558 llvm::raw_svector_ostream OS(Str);
3559 OS << *ClassTemplate;
3560 OS << "<";
3561 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3562 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3563 if (I)
3564 OS << ", ";
3565
3566 NamedDecl *Param = Params->getParam(I);
3567 if (Param->getIdentifier()) {
3568 OS << Param->getIdentifier()->getName();
3569 continue;
3570 }
3571
3572 // There is no parameter name, which makes this tricky. Try to come up
3573 // with something useful that isn't too long.
3574 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3575 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3576 else if (NonTypeTemplateParmDecl *NTTP
3577 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3578 OS << NTTP->getType().getAsString(Policy);
3579 else
3580 OS << "template<...> class";
3581 }
3582
3583 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003584 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003585 }
3586
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003587 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003588 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3589 // If the type was explicitly written, use that.
3590 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003591 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003592
Benjamin Kramer9170e912013-02-22 15:46:01 +00003593 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 llvm::raw_svector_ostream OS(Str);
3595 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003596 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003597 ClassSpec->getTemplateArgs().data(),
3598 ClassSpec->getTemplateArgs().size(),
3599 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003600 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003601 }
3602
3603 return clang_getCursorSpelling(C);
3604}
3605
3606CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3607 switch (Kind) {
3608 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003609 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003611 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003612 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003613 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003614 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003615 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003616 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003617 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003618 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003619 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003620 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003621 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003622 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003623 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003624 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003625 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003626 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003627 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003628 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003629 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003630 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003631 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003632 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003633 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003635 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003637 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003641 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003643 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003645 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003647 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003651 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003653 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003655 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003659 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003663 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003665 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003673 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003736 case CXCursor_ObjCSelfExpr:
3737 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003854 case CXCursor_PackedAttr:
3855 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003904 case CXCursor_OMPParallelDirective:
3905 return cxstring::createRef("OMPParallelDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 }
3907
3908 llvm_unreachable("Unhandled CXCursorKind");
3909}
3910
3911struct GetCursorData {
3912 SourceLocation TokenBeginLoc;
3913 bool PointsAtMacroArgExpansion;
3914 bool VisitedObjCPropertyImplDecl;
3915 SourceLocation VisitedDeclaratorDeclStartLoc;
3916 CXCursor &BestCursor;
3917
3918 GetCursorData(SourceManager &SM,
3919 SourceLocation tokenBegin, CXCursor &outputCursor)
3920 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3921 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3922 VisitedObjCPropertyImplDecl = false;
3923 }
3924};
3925
3926static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3927 CXCursor parent,
3928 CXClientData client_data) {
3929 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3930 CXCursor *BestCursor = &Data->BestCursor;
3931
3932 // If we point inside a macro argument we should provide info of what the
3933 // token is so use the actual cursor, don't replace it with a macro expansion
3934 // cursor.
3935 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3936 return CXChildVisit_Recurse;
3937
3938 if (clang_isDeclaration(cursor.kind)) {
3939 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003940 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003941 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3942 if (MD->isImplicit())
3943 return CXChildVisit_Break;
3944
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003945 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3947 // Check that when we have multiple @class references in the same line,
3948 // that later ones do not override the previous ones.
3949 // If we have:
3950 // @class Foo, Bar;
3951 // source ranges for both start at '@', so 'Bar' will end up overriding
3952 // 'Foo' even though the cursor location was at 'Foo'.
3953 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3954 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003955 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3957 if (PrevID != ID &&
3958 !PrevID->isThisDeclarationADefinition() &&
3959 !ID->isThisDeclarationADefinition())
3960 return CXChildVisit_Break;
3961 }
3962
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003963 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003964 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3965 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3966 // Check that when we have multiple declarators in the same line,
3967 // that later ones do not override the previous ones.
3968 // If we have:
3969 // int Foo, Bar;
3970 // source ranges for both start at 'int', so 'Bar' will end up overriding
3971 // 'Foo' even though the cursor location was at 'Foo'.
3972 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3973 return CXChildVisit_Break;
3974 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3975
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003976 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003977 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3978 (void)PropImp;
3979 // Check that when we have multiple @synthesize in the same line,
3980 // that later ones do not override the previous ones.
3981 // If we have:
3982 // @synthesize Foo, Bar;
3983 // source ranges for both start at '@', so 'Bar' will end up overriding
3984 // 'Foo' even though the cursor location was at 'Foo'.
3985 if (Data->VisitedObjCPropertyImplDecl)
3986 return CXChildVisit_Break;
3987 Data->VisitedObjCPropertyImplDecl = true;
3988 }
3989 }
3990
3991 if (clang_isExpression(cursor.kind) &&
3992 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003993 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 // Avoid having the cursor of an expression replace the declaration cursor
3995 // when the expression source range overlaps the declaration range.
3996 // This can happen for C++ constructor expressions whose range generally
3997 // include the variable declaration, e.g.:
3998 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
3999 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4000 D->getLocation() == Data->TokenBeginLoc)
4001 return CXChildVisit_Break;
4002 }
4003 }
4004
4005 // If our current best cursor is the construction of a temporary object,
4006 // don't replace that cursor with a type reference, because we want
4007 // clang_getCursor() to point at the constructor.
4008 if (clang_isExpression(BestCursor->kind) &&
4009 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4010 cursor.kind == CXCursor_TypeRef) {
4011 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4012 // as having the actual point on the type reference.
4013 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4014 return CXChildVisit_Recurse;
4015 }
4016
4017 *BestCursor = cursor;
4018 return CXChildVisit_Recurse;
4019}
4020
4021CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004022 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004023 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004024 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004025 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004026
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004027 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004028 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4029
4030 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4031 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4032
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004033 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 CXFile SearchFile;
4035 unsigned SearchLine, SearchColumn;
4036 CXFile ResultFile;
4037 unsigned ResultLine, ResultColumn;
4038 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4039 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4040 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4041
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004042 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4043 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 &ResultColumn, 0);
4045 SearchFileName = clang_getFileName(SearchFile);
4046 ResultFileName = clang_getFileName(ResultFile);
4047 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4048 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004049 *Log << llvm::format("(%s:%d:%d) = %s",
4050 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4051 clang_getCString(KindSpelling))
4052 << llvm::format("(%s:%d:%d):%s%s",
4053 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4054 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 clang_disposeString(SearchFileName);
4056 clang_disposeString(ResultFileName);
4057 clang_disposeString(KindSpelling);
4058 clang_disposeString(USR);
4059
4060 CXCursor Definition = clang_getCursorDefinition(Result);
4061 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4062 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4063 CXString DefinitionKindSpelling
4064 = clang_getCursorKindSpelling(Definition.kind);
4065 CXFile DefinitionFile;
4066 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004067 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 &DefinitionLine, &DefinitionColumn, 0);
4069 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004070 *Log << llvm::format(" -> %s(%s:%d:%d)",
4071 clang_getCString(DefinitionKindSpelling),
4072 clang_getCString(DefinitionFileName),
4073 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 clang_disposeString(DefinitionFileName);
4075 clang_disposeString(DefinitionKindSpelling);
4076 }
4077 }
4078
4079 return Result;
4080}
4081
4082CXCursor clang_getNullCursor(void) {
4083 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4084}
4085
4086unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004087 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4088 // can't set consistently. For example, when visiting a DeclStmt we will set
4089 // it but we don't set it on the result of clang_getCursorDefinition for
4090 // a reference of the same declaration.
4091 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4092 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4093 // to provide that kind of info.
4094 if (clang_isDeclaration(X.kind))
4095 X.data[1] = 0;
4096 if (clang_isDeclaration(Y.kind))
4097 Y.data[1] = 0;
4098
Guy Benyei11169dd2012-12-18 14:30:41 +00004099 return X == Y;
4100}
4101
4102unsigned clang_hashCursor(CXCursor C) {
4103 unsigned Index = 0;
4104 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4105 Index = 1;
4106
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004107 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 std::make_pair(C.kind, C.data[Index]));
4109}
4110
4111unsigned clang_isInvalid(enum CXCursorKind K) {
4112 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4113}
4114
4115unsigned clang_isDeclaration(enum CXCursorKind K) {
4116 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4117 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4118}
4119
4120unsigned clang_isReference(enum CXCursorKind K) {
4121 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4122}
4123
4124unsigned clang_isExpression(enum CXCursorKind K) {
4125 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4126}
4127
4128unsigned clang_isStatement(enum CXCursorKind K) {
4129 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4130}
4131
4132unsigned clang_isAttribute(enum CXCursorKind K) {
4133 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4134}
4135
4136unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4137 return K == CXCursor_TranslationUnit;
4138}
4139
4140unsigned clang_isPreprocessing(enum CXCursorKind K) {
4141 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4142}
4143
4144unsigned clang_isUnexposed(enum CXCursorKind K) {
4145 switch (K) {
4146 case CXCursor_UnexposedDecl:
4147 case CXCursor_UnexposedExpr:
4148 case CXCursor_UnexposedStmt:
4149 case CXCursor_UnexposedAttr:
4150 return true;
4151 default:
4152 return false;
4153 }
4154}
4155
4156CXCursorKind clang_getCursorKind(CXCursor C) {
4157 return C.kind;
4158}
4159
4160CXSourceLocation clang_getCursorLocation(CXCursor C) {
4161 if (clang_isReference(C.kind)) {
4162 switch (C.kind) {
4163 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004164 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004165 = getCursorObjCSuperClassRef(C);
4166 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4167 }
4168
4169 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004170 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 = getCursorObjCProtocolRef(C);
4172 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4173 }
4174
4175 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004176 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 = getCursorObjCClassRef(C);
4178 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4179 }
4180
4181 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004182 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4184 }
4185
4186 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004187 std::pair<const TemplateDecl *, SourceLocation> P =
4188 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4190 }
4191
4192 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004193 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004194 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4195 }
4196
4197 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004198 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4200 }
4201
4202 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004203 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004204 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4205 }
4206
4207 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004208 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004209 if (!BaseSpec)
4210 return clang_getNullLocation();
4211
4212 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4213 return cxloc::translateSourceLocation(getCursorContext(C),
4214 TSInfo->getTypeLoc().getBeginLoc());
4215
4216 return cxloc::translateSourceLocation(getCursorContext(C),
4217 BaseSpec->getLocStart());
4218 }
4219
4220 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004221 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4223 }
4224
4225 case CXCursor_OverloadedDeclRef:
4226 return cxloc::translateSourceLocation(getCursorContext(C),
4227 getCursorOverloadedDeclRef(C).second);
4228
4229 default:
4230 // FIXME: Need a way to enumerate all non-reference cases.
4231 llvm_unreachable("Missed a reference kind");
4232 }
4233 }
4234
4235 if (clang_isExpression(C.kind))
4236 return cxloc::translateSourceLocation(getCursorContext(C),
4237 getLocationFromExpr(getCursorExpr(C)));
4238
4239 if (clang_isStatement(C.kind))
4240 return cxloc::translateSourceLocation(getCursorContext(C),
4241 getCursorStmt(C)->getLocStart());
4242
4243 if (C.kind == CXCursor_PreprocessingDirective) {
4244 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4245 return cxloc::translateSourceLocation(getCursorContext(C), L);
4246 }
4247
4248 if (C.kind == CXCursor_MacroExpansion) {
4249 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004250 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004251 return cxloc::translateSourceLocation(getCursorContext(C), L);
4252 }
4253
4254 if (C.kind == CXCursor_MacroDefinition) {
4255 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4256 return cxloc::translateSourceLocation(getCursorContext(C), L);
4257 }
4258
4259 if (C.kind == CXCursor_InclusionDirective) {
4260 SourceLocation L
4261 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4262 return cxloc::translateSourceLocation(getCursorContext(C), L);
4263 }
4264
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004265 if (clang_isAttribute(C.kind)) {
4266 SourceLocation L
4267 = cxcursor::getCursorAttr(C)->getLocation();
4268 return cxloc::translateSourceLocation(getCursorContext(C), L);
4269 }
4270
Guy Benyei11169dd2012-12-18 14:30:41 +00004271 if (!clang_isDeclaration(C.kind))
4272 return clang_getNullLocation();
4273
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004274 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004275 if (!D)
4276 return clang_getNullLocation();
4277
4278 SourceLocation Loc = D->getLocation();
4279 // FIXME: Multiple variables declared in a single declaration
4280 // currently lack the information needed to correctly determine their
4281 // ranges when accounting for the type-specifier. We use context
4282 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4283 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004284 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004285 if (!cxcursor::isFirstInDeclGroup(C))
4286 Loc = VD->getLocation();
4287 }
4288
4289 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004290 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004291 Loc = MD->getSelectorStartLoc();
4292
4293 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4294}
4295
4296} // end extern "C"
4297
4298CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4299 assert(TU);
4300
4301 // Guard against an invalid SourceLocation, or we may assert in one
4302 // of the following calls.
4303 if (SLoc.isInvalid())
4304 return clang_getNullCursor();
4305
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004306 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004307
4308 // Translate the given source location to make it point at the beginning of
4309 // the token under the cursor.
4310 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4311 CXXUnit->getASTContext().getLangOpts());
4312
4313 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4314 if (SLoc.isValid()) {
4315 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4316 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4317 /*VisitPreprocessorLast=*/true,
4318 /*VisitIncludedEntities=*/false,
4319 SourceLocation(SLoc));
4320 CursorVis.visitFileRegion();
4321 }
4322
4323 return Result;
4324}
4325
4326static SourceRange getRawCursorExtent(CXCursor C) {
4327 if (clang_isReference(C.kind)) {
4328 switch (C.kind) {
4329 case CXCursor_ObjCSuperClassRef:
4330 return getCursorObjCSuperClassRef(C).second;
4331
4332 case CXCursor_ObjCProtocolRef:
4333 return getCursorObjCProtocolRef(C).second;
4334
4335 case CXCursor_ObjCClassRef:
4336 return getCursorObjCClassRef(C).second;
4337
4338 case CXCursor_TypeRef:
4339 return getCursorTypeRef(C).second;
4340
4341 case CXCursor_TemplateRef:
4342 return getCursorTemplateRef(C).second;
4343
4344 case CXCursor_NamespaceRef:
4345 return getCursorNamespaceRef(C).second;
4346
4347 case CXCursor_MemberRef:
4348 return getCursorMemberRef(C).second;
4349
4350 case CXCursor_CXXBaseSpecifier:
4351 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4352
4353 case CXCursor_LabelRef:
4354 return getCursorLabelRef(C).second;
4355
4356 case CXCursor_OverloadedDeclRef:
4357 return getCursorOverloadedDeclRef(C).second;
4358
4359 case CXCursor_VariableRef:
4360 return getCursorVariableRef(C).second;
4361
4362 default:
4363 // FIXME: Need a way to enumerate all non-reference cases.
4364 llvm_unreachable("Missed a reference kind");
4365 }
4366 }
4367
4368 if (clang_isExpression(C.kind))
4369 return getCursorExpr(C)->getSourceRange();
4370
4371 if (clang_isStatement(C.kind))
4372 return getCursorStmt(C)->getSourceRange();
4373
4374 if (clang_isAttribute(C.kind))
4375 return getCursorAttr(C)->getRange();
4376
4377 if (C.kind == CXCursor_PreprocessingDirective)
4378 return cxcursor::getCursorPreprocessingDirective(C);
4379
4380 if (C.kind == CXCursor_MacroExpansion) {
4381 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004382 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004383 return TU->mapRangeFromPreamble(Range);
4384 }
4385
4386 if (C.kind == CXCursor_MacroDefinition) {
4387 ASTUnit *TU = getCursorASTUnit(C);
4388 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4389 return TU->mapRangeFromPreamble(Range);
4390 }
4391
4392 if (C.kind == CXCursor_InclusionDirective) {
4393 ASTUnit *TU = getCursorASTUnit(C);
4394 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4395 return TU->mapRangeFromPreamble(Range);
4396 }
4397
4398 if (C.kind == CXCursor_TranslationUnit) {
4399 ASTUnit *TU = getCursorASTUnit(C);
4400 FileID MainID = TU->getSourceManager().getMainFileID();
4401 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4402 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4403 return SourceRange(Start, End);
4404 }
4405
4406 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004407 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004408 if (!D)
4409 return SourceRange();
4410
4411 SourceRange R = D->getSourceRange();
4412 // FIXME: Multiple variables declared in a single declaration
4413 // currently lack the information needed to correctly determine their
4414 // ranges when accounting for the type-specifier. We use context
4415 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4416 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004417 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004418 if (!cxcursor::isFirstInDeclGroup(C))
4419 R.setBegin(VD->getLocation());
4420 }
4421 return R;
4422 }
4423 return SourceRange();
4424}
4425
4426/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4427/// the decl-specifier-seq for declarations.
4428static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4429 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004430 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004431 if (!D)
4432 return SourceRange();
4433
4434 SourceRange R = D->getSourceRange();
4435
4436 // Adjust the start of the location for declarations preceded by
4437 // declaration specifiers.
4438 SourceLocation StartLoc;
4439 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4440 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4441 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004442 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004443 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4444 StartLoc = TI->getTypeLoc().getLocStart();
4445 }
4446
4447 if (StartLoc.isValid() && R.getBegin().isValid() &&
4448 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4449 R.setBegin(StartLoc);
4450
4451 // FIXME: Multiple variables declared in a single declaration
4452 // currently lack the information needed to correctly determine their
4453 // ranges when accounting for the type-specifier. We use context
4454 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4455 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004456 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004457 if (!cxcursor::isFirstInDeclGroup(C))
4458 R.setBegin(VD->getLocation());
4459 }
4460
4461 return R;
4462 }
4463
4464 return getRawCursorExtent(C);
4465}
4466
4467extern "C" {
4468
4469CXSourceRange clang_getCursorExtent(CXCursor C) {
4470 SourceRange R = getRawCursorExtent(C);
4471 if (R.isInvalid())
4472 return clang_getNullRange();
4473
4474 return cxloc::translateSourceRange(getCursorContext(C), R);
4475}
4476
4477CXCursor clang_getCursorReferenced(CXCursor C) {
4478 if (clang_isInvalid(C.kind))
4479 return clang_getNullCursor();
4480
4481 CXTranslationUnit tu = getCursorTU(C);
4482 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004483 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004484 if (!D)
4485 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004486 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004487 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004488 if (const ObjCPropertyImplDecl *PropImpl =
4489 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004490 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4491 return MakeCXCursor(Property, tu);
4492
4493 return C;
4494 }
4495
4496 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004497 const Expr *E = getCursorExpr(C);
4498 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004499 if (D) {
4500 CXCursor declCursor = MakeCXCursor(D, tu);
4501 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4502 declCursor);
4503 return declCursor;
4504 }
4505
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004506 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004507 return MakeCursorOverloadedDeclRef(Ovl, tu);
4508
4509 return clang_getNullCursor();
4510 }
4511
4512 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004513 const Stmt *S = getCursorStmt(C);
4514 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004515 if (LabelDecl *label = Goto->getLabel())
4516 if (LabelStmt *labelS = label->getStmt())
4517 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4518
4519 return clang_getNullCursor();
4520 }
4521
4522 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004523 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004524 return MakeMacroDefinitionCursor(Def, tu);
4525 }
4526
4527 if (!clang_isReference(C.kind))
4528 return clang_getNullCursor();
4529
4530 switch (C.kind) {
4531 case CXCursor_ObjCSuperClassRef:
4532 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4533
4534 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004535 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4536 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 return MakeCXCursor(Def, tu);
4538
4539 return MakeCXCursor(Prot, tu);
4540 }
4541
4542 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004543 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4544 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004545 return MakeCXCursor(Def, tu);
4546
4547 return MakeCXCursor(Class, tu);
4548 }
4549
4550 case CXCursor_TypeRef:
4551 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4552
4553 case CXCursor_TemplateRef:
4554 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4555
4556 case CXCursor_NamespaceRef:
4557 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4558
4559 case CXCursor_MemberRef:
4560 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4561
4562 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004563 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004564 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4565 tu ));
4566 }
4567
4568 case CXCursor_LabelRef:
4569 // FIXME: We end up faking the "parent" declaration here because we
4570 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004571 return MakeCXCursor(getCursorLabelRef(C).first,
4572 cxtu::getASTUnit(tu)->getASTContext()
4573 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004574 tu);
4575
4576 case CXCursor_OverloadedDeclRef:
4577 return C;
4578
4579 case CXCursor_VariableRef:
4580 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4581
4582 default:
4583 // We would prefer to enumerate all non-reference cursor kinds here.
4584 llvm_unreachable("Unhandled reference cursor kind");
4585 }
4586}
4587
4588CXCursor clang_getCursorDefinition(CXCursor C) {
4589 if (clang_isInvalid(C.kind))
4590 return clang_getNullCursor();
4591
4592 CXTranslationUnit TU = getCursorTU(C);
4593
4594 bool WasReference = false;
4595 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4596 C = clang_getCursorReferenced(C);
4597 WasReference = true;
4598 }
4599
4600 if (C.kind == CXCursor_MacroExpansion)
4601 return clang_getCursorReferenced(C);
4602
4603 if (!clang_isDeclaration(C.kind))
4604 return clang_getNullCursor();
4605
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004606 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004607 if (!D)
4608 return clang_getNullCursor();
4609
4610 switch (D->getKind()) {
4611 // Declaration kinds that don't really separate the notions of
4612 // declaration and definition.
4613 case Decl::Namespace:
4614 case Decl::Typedef:
4615 case Decl::TypeAlias:
4616 case Decl::TypeAliasTemplate:
4617 case Decl::TemplateTypeParm:
4618 case Decl::EnumConstant:
4619 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004620 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 case Decl::IndirectField:
4622 case Decl::ObjCIvar:
4623 case Decl::ObjCAtDefsField:
4624 case Decl::ImplicitParam:
4625 case Decl::ParmVar:
4626 case Decl::NonTypeTemplateParm:
4627 case Decl::TemplateTemplateParm:
4628 case Decl::ObjCCategoryImpl:
4629 case Decl::ObjCImplementation:
4630 case Decl::AccessSpec:
4631 case Decl::LinkageSpec:
4632 case Decl::ObjCPropertyImpl:
4633 case Decl::FileScopeAsm:
4634 case Decl::StaticAssert:
4635 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004636 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 case Decl::Label: // FIXME: Is this right??
4638 case Decl::ClassScopeFunctionSpecialization:
4639 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004640 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004641 return C;
4642
4643 // Declaration kinds that don't make any sense here, but are
4644 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004645 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004646 case Decl::TranslationUnit:
4647 break;
4648
4649 // Declaration kinds for which the definition is not resolvable.
4650 case Decl::UnresolvedUsingTypename:
4651 case Decl::UnresolvedUsingValue:
4652 break;
4653
4654 case Decl::UsingDirective:
4655 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4656 TU);
4657
4658 case Decl::NamespaceAlias:
4659 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4660
4661 case Decl::Enum:
4662 case Decl::Record:
4663 case Decl::CXXRecord:
4664 case Decl::ClassTemplateSpecialization:
4665 case Decl::ClassTemplatePartialSpecialization:
4666 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4667 return MakeCXCursor(Def, TU);
4668 return clang_getNullCursor();
4669
4670 case Decl::Function:
4671 case Decl::CXXMethod:
4672 case Decl::CXXConstructor:
4673 case Decl::CXXDestructor:
4674 case Decl::CXXConversion: {
4675 const FunctionDecl *Def = 0;
4676 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004677 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004678 return clang_getNullCursor();
4679 }
4680
Larisse Voufo39a1e502013-08-06 01:03:05 +00004681 case Decl::Var:
4682 case Decl::VarTemplateSpecialization:
4683 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004684 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004685 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004686 return MakeCXCursor(Def, TU);
4687 return clang_getNullCursor();
4688 }
4689
4690 case Decl::FunctionTemplate: {
4691 const FunctionDecl *Def = 0;
4692 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4693 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4694 return clang_getNullCursor();
4695 }
4696
4697 case Decl::ClassTemplate: {
4698 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4699 ->getDefinition())
4700 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4701 TU);
4702 return clang_getNullCursor();
4703 }
4704
Larisse Voufo39a1e502013-08-06 01:03:05 +00004705 case Decl::VarTemplate: {
4706 if (VarDecl *Def =
4707 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4708 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4709 return clang_getNullCursor();
4710 }
4711
Guy Benyei11169dd2012-12-18 14:30:41 +00004712 case Decl::Using:
4713 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4714 D->getLocation(), TU);
4715
4716 case Decl::UsingShadow:
4717 return clang_getCursorDefinition(
4718 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4719 TU));
4720
4721 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004722 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004723 if (Method->isThisDeclarationADefinition())
4724 return C;
4725
4726 // Dig out the method definition in the associated
4727 // @implementation, if we have it.
4728 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004729 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004730 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4731 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4732 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4733 Method->isInstanceMethod()))
4734 if (Def->isThisDeclarationADefinition())
4735 return MakeCXCursor(Def, TU);
4736
4737 return clang_getNullCursor();
4738 }
4739
4740 case Decl::ObjCCategory:
4741 if (ObjCCategoryImplDecl *Impl
4742 = cast<ObjCCategoryDecl>(D)->getImplementation())
4743 return MakeCXCursor(Impl, TU);
4744 return clang_getNullCursor();
4745
4746 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004747 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004748 return MakeCXCursor(Def, TU);
4749 return clang_getNullCursor();
4750
4751 case Decl::ObjCInterface: {
4752 // There are two notions of a "definition" for an Objective-C
4753 // class: the interface and its implementation. When we resolved a
4754 // reference to an Objective-C class, produce the @interface as
4755 // the definition; when we were provided with the interface,
4756 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004757 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004758 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004759 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004760 return MakeCXCursor(Def, TU);
4761 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4762 return MakeCXCursor(Impl, TU);
4763 return clang_getNullCursor();
4764 }
4765
4766 case Decl::ObjCProperty:
4767 // FIXME: We don't really know where to find the
4768 // ObjCPropertyImplDecls that implement this property.
4769 return clang_getNullCursor();
4770
4771 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004772 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004773 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004774 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004775 return MakeCXCursor(Def, TU);
4776
4777 return clang_getNullCursor();
4778
4779 case Decl::Friend:
4780 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4781 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4782 return clang_getNullCursor();
4783
4784 case Decl::FriendTemplate:
4785 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4786 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4787 return clang_getNullCursor();
4788 }
4789
4790 return clang_getNullCursor();
4791}
4792
4793unsigned clang_isCursorDefinition(CXCursor C) {
4794 if (!clang_isDeclaration(C.kind))
4795 return 0;
4796
4797 return clang_getCursorDefinition(C) == C;
4798}
4799
4800CXCursor clang_getCanonicalCursor(CXCursor C) {
4801 if (!clang_isDeclaration(C.kind))
4802 return C;
4803
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004804 if (const Decl *D = getCursorDecl(C)) {
4805 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004806 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4807 return MakeCXCursor(CatD, getCursorTU(C));
4808
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004809 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4810 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004811 return MakeCXCursor(IFD, getCursorTU(C));
4812
4813 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4814 }
4815
4816 return C;
4817}
4818
4819int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4820 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4821}
4822
4823unsigned clang_getNumOverloadedDecls(CXCursor C) {
4824 if (C.kind != CXCursor_OverloadedDeclRef)
4825 return 0;
4826
4827 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004828 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004829 return E->getNumDecls();
4830
4831 if (OverloadedTemplateStorage *S
4832 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4833 return S->size();
4834
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004835 const Decl *D = Storage.get<const Decl *>();
4836 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004837 return Using->shadow_size();
4838
4839 return 0;
4840}
4841
4842CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4843 if (cursor.kind != CXCursor_OverloadedDeclRef)
4844 return clang_getNullCursor();
4845
4846 if (index >= clang_getNumOverloadedDecls(cursor))
4847 return clang_getNullCursor();
4848
4849 CXTranslationUnit TU = getCursorTU(cursor);
4850 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004851 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004852 return MakeCXCursor(E->decls_begin()[index], TU);
4853
4854 if (OverloadedTemplateStorage *S
4855 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4856 return MakeCXCursor(S->begin()[index], TU);
4857
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004858 const Decl *D = Storage.get<const Decl *>();
4859 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004860 // FIXME: This is, unfortunately, linear time.
4861 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4862 std::advance(Pos, index);
4863 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4864 }
4865
4866 return clang_getNullCursor();
4867}
4868
4869void clang_getDefinitionSpellingAndExtent(CXCursor C,
4870 const char **startBuf,
4871 const char **endBuf,
4872 unsigned *startLine,
4873 unsigned *startColumn,
4874 unsigned *endLine,
4875 unsigned *endColumn) {
4876 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004877 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004878 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4879
4880 SourceManager &SM = FD->getASTContext().getSourceManager();
4881 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4882 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4883 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4884 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4885 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4886 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4887}
4888
4889
4890CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4891 unsigned PieceIndex) {
4892 RefNamePieces Pieces;
4893
4894 switch (C.kind) {
4895 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004896 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004897 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4898 E->getQualifierLoc().getSourceRange());
4899 break;
4900
4901 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004902 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004903 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4904 E->getQualifierLoc().getSourceRange(),
4905 E->getOptionalExplicitTemplateArgs());
4906 break;
4907
4908 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004909 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004910 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004911 const Expr *Callee = OCE->getCallee();
4912 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004913 Callee = ICE->getSubExpr();
4914
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004915 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004916 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4917 DRE->getQualifierLoc().getSourceRange());
4918 }
4919 break;
4920
4921 default:
4922 break;
4923 }
4924
4925 if (Pieces.empty()) {
4926 if (PieceIndex == 0)
4927 return clang_getCursorExtent(C);
4928 } else if (PieceIndex < Pieces.size()) {
4929 SourceRange R = Pieces[PieceIndex];
4930 if (R.isValid())
4931 return cxloc::translateSourceRange(getCursorContext(C), R);
4932 }
4933
4934 return clang_getNullRange();
4935}
4936
4937void clang_enableStackTraces(void) {
4938 llvm::sys::PrintStackTraceOnErrorSignal();
4939}
4940
4941void clang_executeOnThread(void (*fn)(void*), void *user_data,
4942 unsigned stack_size) {
4943 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4944}
4945
4946} // end: extern "C"
4947
4948//===----------------------------------------------------------------------===//
4949// Token-based Operations.
4950//===----------------------------------------------------------------------===//
4951
4952/* CXToken layout:
4953 * int_data[0]: a CXTokenKind
4954 * int_data[1]: starting token location
4955 * int_data[2]: token length
4956 * int_data[3]: reserved
4957 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4958 * otherwise unused.
4959 */
4960extern "C" {
4961
4962CXTokenKind clang_getTokenKind(CXToken CXTok) {
4963 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4964}
4965
4966CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4967 switch (clang_getTokenKind(CXTok)) {
4968 case CXToken_Identifier:
4969 case CXToken_Keyword:
4970 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004971 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004972 ->getNameStart());
4973
4974 case CXToken_Literal: {
4975 // We have stashed the starting pointer in the ptr_data field. Use it.
4976 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004977 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004978 }
4979
4980 case CXToken_Punctuation:
4981 case CXToken_Comment:
4982 break;
4983 }
4984
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004985 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004986 LOG_BAD_TU(TU);
4987 return cxstring::createEmpty();
4988 }
4989
Guy Benyei11169dd2012-12-18 14:30:41 +00004990 // We have to find the starting buffer pointer the hard way, by
4991 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004992 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004993 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004994 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004995
4996 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4997 std::pair<FileID, unsigned> LocInfo
4998 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
4999 bool Invalid = false;
5000 StringRef Buffer
5001 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5002 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005003 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005004
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005005 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005006}
5007
5008CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005009 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005010 LOG_BAD_TU(TU);
5011 return clang_getNullLocation();
5012 }
5013
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005014 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005015 if (!CXXUnit)
5016 return clang_getNullLocation();
5017
5018 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5019 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5020}
5021
5022CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005023 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005024 LOG_BAD_TU(TU);
5025 return clang_getNullRange();
5026 }
5027
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005028 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005029 if (!CXXUnit)
5030 return clang_getNullRange();
5031
5032 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5033 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5034}
5035
5036static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5037 SmallVectorImpl<CXToken> &CXTokens) {
5038 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5039 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005040 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005041 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005042 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005043
5044 // Cannot tokenize across files.
5045 if (BeginLocInfo.first != EndLocInfo.first)
5046 return;
5047
5048 // Create a lexer
5049 bool Invalid = false;
5050 StringRef Buffer
5051 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5052 if (Invalid)
5053 return;
5054
5055 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5056 CXXUnit->getASTContext().getLangOpts(),
5057 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5058 Lex.SetCommentRetentionState(true);
5059
5060 // Lex tokens until we hit the end of the range.
5061 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5062 Token Tok;
5063 bool previousWasAt = false;
5064 do {
5065 // Lex the next token
5066 Lex.LexFromRawLexer(Tok);
5067 if (Tok.is(tok::eof))
5068 break;
5069
5070 // Initialize the CXToken.
5071 CXToken CXTok;
5072
5073 // - Common fields
5074 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5075 CXTok.int_data[2] = Tok.getLength();
5076 CXTok.int_data[3] = 0;
5077
5078 // - Kind-specific fields
5079 if (Tok.isLiteral()) {
5080 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005081 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005082 } else if (Tok.is(tok::raw_identifier)) {
5083 // Lookup the identifier to determine whether we have a keyword.
5084 IdentifierInfo *II
5085 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5086
5087 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5088 CXTok.int_data[0] = CXToken_Keyword;
5089 }
5090 else {
5091 CXTok.int_data[0] = Tok.is(tok::identifier)
5092 ? CXToken_Identifier
5093 : CXToken_Keyword;
5094 }
5095 CXTok.ptr_data = II;
5096 } else if (Tok.is(tok::comment)) {
5097 CXTok.int_data[0] = CXToken_Comment;
5098 CXTok.ptr_data = 0;
5099 } else {
5100 CXTok.int_data[0] = CXToken_Punctuation;
5101 CXTok.ptr_data = 0;
5102 }
5103 CXTokens.push_back(CXTok);
5104 previousWasAt = Tok.is(tok::at);
5105 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5106}
5107
5108void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5109 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005110 LOG_FUNC_SECTION {
5111 *Log << TU << ' ' << Range;
5112 }
5113
Guy Benyei11169dd2012-12-18 14:30:41 +00005114 if (Tokens)
5115 *Tokens = 0;
5116 if (NumTokens)
5117 *NumTokens = 0;
5118
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005119 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005120 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005121 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005122 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005123
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005124 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005125 if (!CXXUnit || !Tokens || !NumTokens)
5126 return;
5127
5128 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5129
5130 SourceRange R = cxloc::translateCXSourceRange(Range);
5131 if (R.isInvalid())
5132 return;
5133
5134 SmallVector<CXToken, 32> CXTokens;
5135 getTokens(CXXUnit, R, CXTokens);
5136
5137 if (CXTokens.empty())
5138 return;
5139
5140 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5141 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5142 *NumTokens = CXTokens.size();
5143}
5144
5145void clang_disposeTokens(CXTranslationUnit TU,
5146 CXToken *Tokens, unsigned NumTokens) {
5147 free(Tokens);
5148}
5149
5150} // end: extern "C"
5151
5152//===----------------------------------------------------------------------===//
5153// Token annotation APIs.
5154//===----------------------------------------------------------------------===//
5155
Guy Benyei11169dd2012-12-18 14:30:41 +00005156static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5157 CXCursor parent,
5158 CXClientData client_data);
5159static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5160 CXClientData client_data);
5161
5162namespace {
5163class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005164 CXToken *Tokens;
5165 CXCursor *Cursors;
5166 unsigned NumTokens;
5167 unsigned TokIdx;
5168 unsigned PreprocessingTokIdx;
5169 CursorVisitor AnnotateVis;
5170 SourceManager &SrcMgr;
5171 bool HasContextSensitiveKeywords;
5172
5173 struct PostChildrenInfo {
5174 CXCursor Cursor;
5175 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005176 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005177 unsigned BeforeChildrenTokenIdx;
5178 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005179 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005180
5181 CXToken &getTok(unsigned Idx) {
5182 assert(Idx < NumTokens);
5183 return Tokens[Idx];
5184 }
5185 const CXToken &getTok(unsigned Idx) const {
5186 assert(Idx < NumTokens);
5187 return Tokens[Idx];
5188 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005189 bool MoreTokens() const { return TokIdx < NumTokens; }
5190 unsigned NextToken() const { return TokIdx; }
5191 void AdvanceToken() { ++TokIdx; }
5192 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005193 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005194 }
5195 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005196 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005197 }
5198 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005199 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005200 }
5201
5202 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005203 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 SourceRange);
5205
5206public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005207 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005208 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005209 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005211 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005212 AnnotateTokensVisitor, this,
5213 /*VisitPreprocessorLast=*/true,
5214 /*VisitIncludedEntities=*/false,
5215 RegionOfInterest,
5216 /*VisitDeclsOnly=*/false,
5217 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005218 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005219 HasContextSensitiveKeywords(false) { }
5220
5221 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5222 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5223 bool postVisitChildren(CXCursor cursor);
5224 void AnnotateTokens();
5225
5226 /// \brief Determine whether the annotator saw any cursors that have
5227 /// context-sensitive keywords.
5228 bool hasContextSensitiveKeywords() const {
5229 return HasContextSensitiveKeywords;
5230 }
5231
5232 ~AnnotateTokensWorker() {
5233 assert(PostChildrenInfos.empty());
5234 }
5235};
5236}
5237
5238void AnnotateTokensWorker::AnnotateTokens() {
5239 // Walk the AST within the region of interest, annotating tokens
5240 // along the way.
5241 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005242}
Guy Benyei11169dd2012-12-18 14:30:41 +00005243
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005244static inline void updateCursorAnnotation(CXCursor &Cursor,
5245 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005246 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005247 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005248 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005249}
5250
5251/// \brief It annotates and advances tokens with a cursor until the comparison
5252//// between the cursor location and the source range is the same as
5253/// \arg compResult.
5254///
5255/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5256/// Pass RangeOverlap to annotate tokens inside a range.
5257void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5258 RangeComparisonResult compResult,
5259 SourceRange range) {
5260 while (MoreTokens()) {
5261 const unsigned I = NextToken();
5262 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005263 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5264 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005265
5266 SourceLocation TokLoc = GetTokenLoc(I);
5267 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005268 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005269 AdvanceToken();
5270 continue;
5271 }
5272 break;
5273 }
5274}
5275
5276/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005277/// \returns true if it advanced beyond all macro tokens, false otherwise.
5278bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005279 CXCursor updateC,
5280 RangeComparisonResult compResult,
5281 SourceRange range) {
5282 assert(MoreTokens());
5283 assert(isFunctionMacroToken(NextToken()) &&
5284 "Should be called only for macro arg tokens");
5285
5286 // This works differently than annotateAndAdvanceTokens; because expanded
5287 // macro arguments can have arbitrary translation-unit source order, we do not
5288 // advance the token index one by one until a token fails the range test.
5289 // We only advance once past all of the macro arg tokens if all of them
5290 // pass the range test. If one of them fails we keep the token index pointing
5291 // at the start of the macro arg tokens so that the failing token will be
5292 // annotated by a subsequent annotation try.
5293
5294 bool atLeastOneCompFail = false;
5295
5296 unsigned I = NextToken();
5297 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5298 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5299 if (TokLoc.isFileID())
5300 continue; // not macro arg token, it's parens or comma.
5301 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5302 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5303 Cursors[I] = updateC;
5304 } else
5305 atLeastOneCompFail = true;
5306 }
5307
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005308 if (atLeastOneCompFail)
5309 return false;
5310
5311 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5312 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005313}
5314
5315enum CXChildVisitResult
5316AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005317 SourceRange cursorRange = getRawCursorExtent(cursor);
5318 if (cursorRange.isInvalid())
5319 return CXChildVisit_Recurse;
5320
5321 if (!HasContextSensitiveKeywords) {
5322 // Objective-C properties can have context-sensitive keywords.
5323 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005324 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005325 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5326 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5327 }
5328 // Objective-C methods can have context-sensitive keywords.
5329 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5330 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005331 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005332 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5333 if (Method->getObjCDeclQualifier())
5334 HasContextSensitiveKeywords = true;
5335 else {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005336 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5337 PEnd = Method->param_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00005338 P != PEnd; ++P) {
5339 if ((*P)->getObjCDeclQualifier()) {
5340 HasContextSensitiveKeywords = true;
5341 break;
5342 }
5343 }
5344 }
5345 }
5346 }
5347 // C++ methods can have context-sensitive keywords.
5348 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005349 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005350 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5351 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5352 HasContextSensitiveKeywords = true;
5353 }
5354 }
5355 // C++ classes can have context-sensitive keywords.
5356 else if (cursor.kind == CXCursor_StructDecl ||
5357 cursor.kind == CXCursor_ClassDecl ||
5358 cursor.kind == CXCursor_ClassTemplate ||
5359 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005360 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005361 if (D->hasAttr<FinalAttr>())
5362 HasContextSensitiveKeywords = true;
5363 }
5364 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005365
5366 // Don't override a property annotation with its getter/setter method.
5367 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5368 parent.kind == CXCursor_ObjCPropertyDecl)
5369 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005370
5371 if (clang_isPreprocessing(cursor.kind)) {
5372 // Items in the preprocessing record are kept separate from items in
5373 // declarations, so we keep a separate token index.
5374 unsigned SavedTokIdx = TokIdx;
5375 TokIdx = PreprocessingTokIdx;
5376
5377 // Skip tokens up until we catch up to the beginning of the preprocessing
5378 // entry.
5379 while (MoreTokens()) {
5380 const unsigned I = NextToken();
5381 SourceLocation TokLoc = GetTokenLoc(I);
5382 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5383 case RangeBefore:
5384 AdvanceToken();
5385 continue;
5386 case RangeAfter:
5387 case RangeOverlap:
5388 break;
5389 }
5390 break;
5391 }
5392
5393 // Look at all of the tokens within this range.
5394 while (MoreTokens()) {
5395 const unsigned I = NextToken();
5396 SourceLocation TokLoc = GetTokenLoc(I);
5397 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5398 case RangeBefore:
5399 llvm_unreachable("Infeasible");
5400 case RangeAfter:
5401 break;
5402 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005403 // For macro expansions, just note where the beginning of the macro
5404 // expansion occurs.
5405 if (cursor.kind == CXCursor_MacroExpansion) {
5406 if (TokLoc == cursorRange.getBegin())
5407 Cursors[I] = cursor;
5408 AdvanceToken();
5409 break;
5410 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005411 // We may have already annotated macro names inside macro definitions.
5412 if (Cursors[I].kind != CXCursor_MacroExpansion)
5413 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005414 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005415 continue;
5416 }
5417 break;
5418 }
5419
5420 // Save the preprocessing token index; restore the non-preprocessing
5421 // token index.
5422 PreprocessingTokIdx = TokIdx;
5423 TokIdx = SavedTokIdx;
5424 return CXChildVisit_Recurse;
5425 }
5426
5427 if (cursorRange.isInvalid())
5428 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005429
5430 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005431 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005432 const enum CXCursorKind K = clang_getCursorKind(parent);
5433 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005434 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5435 // Attributes are annotated out-of-order, skip tokens until we reach it.
5436 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005437 ? clang_getNullCursor() : parent;
5438
5439 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5440
5441 // Avoid having the cursor of an expression "overwrite" the annotation of the
5442 // variable declaration that it belongs to.
5443 // This can happen for C++ constructor expressions whose range generally
5444 // include the variable declaration, e.g.:
5445 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005446 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005447 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005448 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005449 const unsigned I = NextToken();
5450 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5451 E->getLocStart() == D->getLocation() &&
5452 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005453 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005454 AdvanceToken();
5455 }
5456 }
5457 }
5458
5459 // Before recursing into the children keep some state that we are going
5460 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5461 // extra work after the child nodes are visited.
5462 // Note that we don't call VisitChildren here to avoid traversing statements
5463 // code-recursively which can blow the stack.
5464
5465 PostChildrenInfo Info;
5466 Info.Cursor = cursor;
5467 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005468 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005469 Info.BeforeChildrenTokenIdx = NextToken();
5470 PostChildrenInfos.push_back(Info);
5471
5472 return CXChildVisit_Recurse;
5473}
5474
5475bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5476 if (PostChildrenInfos.empty())
5477 return false;
5478 const PostChildrenInfo &Info = PostChildrenInfos.back();
5479 if (!clang_equalCursors(Info.Cursor, cursor))
5480 return false;
5481
5482 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5483 const unsigned AfterChildren = NextToken();
5484 SourceRange cursorRange = Info.CursorRange;
5485
5486 // Scan the tokens that are at the end of the cursor, but are not captured
5487 // but the child cursors.
5488 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5489
5490 // Scan the tokens that are at the beginning of the cursor, but are not
5491 // capture by the child cursors.
5492 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5493 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5494 break;
5495
5496 Cursors[I] = cursor;
5497 }
5498
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005499 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5500 // encountered the attribute cursor.
5501 if (clang_isAttribute(cursor.kind))
5502 TokIdx = Info.BeforeReachingCursorIdx;
5503
Guy Benyei11169dd2012-12-18 14:30:41 +00005504 PostChildrenInfos.pop_back();
5505 return false;
5506}
5507
5508static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5509 CXCursor parent,
5510 CXClientData client_data) {
5511 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5512}
5513
5514static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5515 CXClientData client_data) {
5516 return static_cast<AnnotateTokensWorker*>(client_data)->
5517 postVisitChildren(cursor);
5518}
5519
5520namespace {
5521
5522/// \brief Uses the macro expansions in the preprocessing record to find
5523/// and mark tokens that are macro arguments. This info is used by the
5524/// AnnotateTokensWorker.
5525class MarkMacroArgTokensVisitor {
5526 SourceManager &SM;
5527 CXToken *Tokens;
5528 unsigned NumTokens;
5529 unsigned CurIdx;
5530
5531public:
5532 MarkMacroArgTokensVisitor(SourceManager &SM,
5533 CXToken *tokens, unsigned numTokens)
5534 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5535
5536 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5537 if (cursor.kind != CXCursor_MacroExpansion)
5538 return CXChildVisit_Continue;
5539
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005540 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005541 if (macroRange.getBegin() == macroRange.getEnd())
5542 return CXChildVisit_Continue; // it's not a function macro.
5543
5544 for (; CurIdx < NumTokens; ++CurIdx) {
5545 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5546 macroRange.getBegin()))
5547 break;
5548 }
5549
5550 if (CurIdx == NumTokens)
5551 return CXChildVisit_Break;
5552
5553 for (; CurIdx < NumTokens; ++CurIdx) {
5554 SourceLocation tokLoc = getTokenLoc(CurIdx);
5555 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5556 break;
5557
5558 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5559 }
5560
5561 if (CurIdx == NumTokens)
5562 return CXChildVisit_Break;
5563
5564 return CXChildVisit_Continue;
5565 }
5566
5567private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005568 CXToken &getTok(unsigned Idx) {
5569 assert(Idx < NumTokens);
5570 return Tokens[Idx];
5571 }
5572 const CXToken &getTok(unsigned Idx) const {
5573 assert(Idx < NumTokens);
5574 return Tokens[Idx];
5575 }
5576
Guy Benyei11169dd2012-12-18 14:30:41 +00005577 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005578 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005579 }
5580
5581 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5582 // The third field is reserved and currently not used. Use it here
5583 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005584 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005585 }
5586};
5587
5588} // end anonymous namespace
5589
5590static CXChildVisitResult
5591MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5592 CXClientData client_data) {
5593 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5594 parent);
5595}
5596
5597namespace {
5598 struct clang_annotateTokens_Data {
5599 CXTranslationUnit TU;
5600 ASTUnit *CXXUnit;
5601 CXToken *Tokens;
5602 unsigned NumTokens;
5603 CXCursor *Cursors;
5604 };
5605}
5606
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005607/// \brief Used by \c annotatePreprocessorTokens.
5608/// \returns true if lexing was finished, false otherwise.
5609static bool lexNext(Lexer &Lex, Token &Tok,
5610 unsigned &NextIdx, unsigned NumTokens) {
5611 if (NextIdx >= NumTokens)
5612 return true;
5613
5614 ++NextIdx;
5615 Lex.LexFromRawLexer(Tok);
5616 if (Tok.is(tok::eof))
5617 return true;
5618
5619 return false;
5620}
5621
Guy Benyei11169dd2012-12-18 14:30:41 +00005622static void annotatePreprocessorTokens(CXTranslationUnit TU,
5623 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005624 CXCursor *Cursors,
5625 CXToken *Tokens,
5626 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005627 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005628
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005629 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005630 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5631 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005632 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005633 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005634 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005635
5636 if (BeginLocInfo.first != EndLocInfo.first)
5637 return;
5638
5639 StringRef Buffer;
5640 bool Invalid = false;
5641 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5642 if (Buffer.empty() || Invalid)
5643 return;
5644
5645 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5646 CXXUnit->getASTContext().getLangOpts(),
5647 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5648 Buffer.end());
5649 Lex.SetCommentRetentionState(true);
5650
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005651 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005652 // Lex tokens in raw mode until we hit the end of the range, to avoid
5653 // entering #includes or expanding macros.
5654 while (true) {
5655 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005656 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5657 break;
5658 unsigned TokIdx = NextIdx-1;
5659 assert(Tok.getLocation() ==
5660 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005661
5662 reprocess:
5663 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005664 // We have found a preprocessing directive. Annotate the tokens
5665 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005666 //
5667 // FIXME: Some simple tests here could identify macro definitions and
5668 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005669
5670 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005671 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5672 break;
5673
5674 MacroInfo *MI = 0;
5675 if (Tok.is(tok::raw_identifier) &&
5676 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5677 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5678 break;
5679
5680 if (Tok.is(tok::raw_identifier)) {
5681 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5682 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5683 SourceLocation MappedTokLoc =
5684 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5685 MI = getMacroInfo(II, MappedTokLoc, TU);
5686 }
5687 }
5688
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005689 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005690 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005691 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5692 finished = true;
5693 break;
5694 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005695 // If we are in a macro definition, check if the token was ever a
5696 // macro name and annotate it if that's the case.
5697 if (MI) {
5698 SourceLocation SaveLoc = Tok.getLocation();
5699 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5700 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5701 Tok.setLocation(SaveLoc);
5702 if (MacroDef)
5703 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5704 Tok.getLocation(), TU);
5705 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005706 } while (!Tok.isAtStartOfLine());
5707
5708 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5709 assert(TokIdx <= LastIdx);
5710 SourceLocation EndLoc =
5711 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5712 CXCursor Cursor =
5713 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5714
5715 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005716 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005717
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005718 if (finished)
5719 break;
5720 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005721 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005722 }
5723}
5724
5725// This gets run a separate thread to avoid stack blowout.
5726static void clang_annotateTokensImpl(void *UserData) {
5727 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5728 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5729 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5730 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5731 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5732
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005733 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005734 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5735 setThreadBackgroundPriority();
5736
5737 // Determine the region of interest, which contains all of the tokens.
5738 SourceRange RegionOfInterest;
5739 RegionOfInterest.setBegin(
5740 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5741 RegionOfInterest.setEnd(
5742 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5743 Tokens[NumTokens-1])));
5744
Guy Benyei11169dd2012-12-18 14:30:41 +00005745 // Relex the tokens within the source range to look for preprocessing
5746 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005747 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005748
5749 // If begin location points inside a macro argument, set it to the expansion
5750 // location so we can have the full context when annotating semantically.
5751 {
5752 SourceManager &SM = CXXUnit->getSourceManager();
5753 SourceLocation Loc =
5754 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5755 if (Loc.isMacroID())
5756 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5757 }
5758
Guy Benyei11169dd2012-12-18 14:30:41 +00005759 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5760 // Search and mark tokens that are macro argument expansions.
5761 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5762 Tokens, NumTokens);
5763 CursorVisitor MacroArgMarker(TU,
5764 MarkMacroArgTokensVisitorDelegate, &Visitor,
5765 /*VisitPreprocessorLast=*/true,
5766 /*VisitIncludedEntities=*/false,
5767 RegionOfInterest);
5768 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5769 }
5770
5771 // Annotate all of the source locations in the region of interest that map to
5772 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005773 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005774
5775 // FIXME: We use a ridiculous stack size here because the data-recursion
5776 // algorithm uses a large stack frame than the non-data recursive version,
5777 // and AnnotationTokensWorker currently transforms the data-recursion
5778 // algorithm back into a traditional recursion by explicitly calling
5779 // VisitChildren(). We will need to remove this explicit recursive call.
5780 W.AnnotateTokens();
5781
5782 // If we ran into any entities that involve context-sensitive keywords,
5783 // take another pass through the tokens to mark them as such.
5784 if (W.hasContextSensitiveKeywords()) {
5785 for (unsigned I = 0; I != NumTokens; ++I) {
5786 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5787 continue;
5788
5789 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5790 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005791 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005792 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5793 if (Property->getPropertyAttributesAsWritten() != 0 &&
5794 llvm::StringSwitch<bool>(II->getName())
5795 .Case("readonly", true)
5796 .Case("assign", true)
5797 .Case("unsafe_unretained", true)
5798 .Case("readwrite", true)
5799 .Case("retain", true)
5800 .Case("copy", true)
5801 .Case("nonatomic", true)
5802 .Case("atomic", true)
5803 .Case("getter", true)
5804 .Case("setter", true)
5805 .Case("strong", true)
5806 .Case("weak", true)
5807 .Default(false))
5808 Tokens[I].int_data[0] = CXToken_Keyword;
5809 }
5810 continue;
5811 }
5812
5813 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5814 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5815 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5816 if (llvm::StringSwitch<bool>(II->getName())
5817 .Case("in", true)
5818 .Case("out", true)
5819 .Case("inout", true)
5820 .Case("oneway", true)
5821 .Case("bycopy", true)
5822 .Case("byref", true)
5823 .Default(false))
5824 Tokens[I].int_data[0] = CXToken_Keyword;
5825 continue;
5826 }
5827
5828 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5829 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5830 Tokens[I].int_data[0] = CXToken_Keyword;
5831 continue;
5832 }
5833 }
5834 }
5835}
5836
5837extern "C" {
5838
5839void clang_annotateTokens(CXTranslationUnit TU,
5840 CXToken *Tokens, unsigned NumTokens,
5841 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005842 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005843 LOG_BAD_TU(TU);
5844 return;
5845 }
5846 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005847 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005848 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005849 }
5850
5851 LOG_FUNC_SECTION {
5852 *Log << TU << ' ';
5853 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5854 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5855 *Log << clang_getRange(bloc, eloc);
5856 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005857
5858 // Any token we don't specifically annotate will have a NULL cursor.
5859 CXCursor C = clang_getNullCursor();
5860 for (unsigned I = 0; I != NumTokens; ++I)
5861 Cursors[I] = C;
5862
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005863 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005864 if (!CXXUnit)
5865 return;
5866
5867 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5868
5869 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5870 llvm::CrashRecoveryContext CRC;
5871 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5872 GetSafetyThreadStackSize() * 2)) {
5873 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5874 }
5875}
5876
5877} // end: extern "C"
5878
5879//===----------------------------------------------------------------------===//
5880// Operations for querying linkage of a cursor.
5881//===----------------------------------------------------------------------===//
5882
5883extern "C" {
5884CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5885 if (!clang_isDeclaration(cursor.kind))
5886 return CXLinkage_Invalid;
5887
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005888 const Decl *D = cxcursor::getCursorDecl(cursor);
5889 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005890 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005891 case NoLinkage:
5892 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005893 case InternalLinkage: return CXLinkage_Internal;
5894 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5895 case ExternalLinkage: return CXLinkage_External;
5896 };
5897
5898 return CXLinkage_Invalid;
5899}
5900} // end: extern "C"
5901
5902//===----------------------------------------------------------------------===//
5903// Operations for querying language of a cursor.
5904//===----------------------------------------------------------------------===//
5905
5906static CXLanguageKind getDeclLanguage(const Decl *D) {
5907 if (!D)
5908 return CXLanguage_C;
5909
5910 switch (D->getKind()) {
5911 default:
5912 break;
5913 case Decl::ImplicitParam:
5914 case Decl::ObjCAtDefsField:
5915 case Decl::ObjCCategory:
5916 case Decl::ObjCCategoryImpl:
5917 case Decl::ObjCCompatibleAlias:
5918 case Decl::ObjCImplementation:
5919 case Decl::ObjCInterface:
5920 case Decl::ObjCIvar:
5921 case Decl::ObjCMethod:
5922 case Decl::ObjCProperty:
5923 case Decl::ObjCPropertyImpl:
5924 case Decl::ObjCProtocol:
5925 return CXLanguage_ObjC;
5926 case Decl::CXXConstructor:
5927 case Decl::CXXConversion:
5928 case Decl::CXXDestructor:
5929 case Decl::CXXMethod:
5930 case Decl::CXXRecord:
5931 case Decl::ClassTemplate:
5932 case Decl::ClassTemplatePartialSpecialization:
5933 case Decl::ClassTemplateSpecialization:
5934 case Decl::Friend:
5935 case Decl::FriendTemplate:
5936 case Decl::FunctionTemplate:
5937 case Decl::LinkageSpec:
5938 case Decl::Namespace:
5939 case Decl::NamespaceAlias:
5940 case Decl::NonTypeTemplateParm:
5941 case Decl::StaticAssert:
5942 case Decl::TemplateTemplateParm:
5943 case Decl::TemplateTypeParm:
5944 case Decl::UnresolvedUsingTypename:
5945 case Decl::UnresolvedUsingValue:
5946 case Decl::Using:
5947 case Decl::UsingDirective:
5948 case Decl::UsingShadow:
5949 return CXLanguage_CPlusPlus;
5950 }
5951
5952 return CXLanguage_C;
5953}
5954
5955extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005956
5957static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5958 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5959 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005960
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005961 switch (D->getAvailability()) {
5962 case AR_Available:
5963 case AR_NotYetIntroduced:
5964 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005965 return getCursorAvailabilityForDecl(
5966 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005967 return CXAvailability_Available;
5968
5969 case AR_Deprecated:
5970 return CXAvailability_Deprecated;
5971
5972 case AR_Unavailable:
5973 return CXAvailability_NotAvailable;
5974 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005975
5976 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005977}
5978
Guy Benyei11169dd2012-12-18 14:30:41 +00005979enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5980 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005981 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5982 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005983
5984 return CXAvailability_Available;
5985}
5986
5987static CXVersion convertVersion(VersionTuple In) {
5988 CXVersion Out = { -1, -1, -1 };
5989 if (In.empty())
5990 return Out;
5991
5992 Out.Major = In.getMajor();
5993
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005994 Optional<unsigned> Minor = In.getMinor();
5995 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00005996 Out.Minor = *Minor;
5997 else
5998 return Out;
5999
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006000 Optional<unsigned> Subminor = In.getSubminor();
6001 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006002 Out.Subminor = *Subminor;
6003
6004 return Out;
6005}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006006
6007static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6008 int *always_deprecated,
6009 CXString *deprecated_message,
6010 int *always_unavailable,
6011 CXString *unavailable_message,
6012 CXPlatformAvailability *availability,
6013 int availability_size) {
6014 bool HadAvailAttr = false;
6015 int N = 0;
6016 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
6017 ++A) {
6018 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
6019 HadAvailAttr = true;
6020 if (always_deprecated)
6021 *always_deprecated = 1;
6022 if (deprecated_message)
6023 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
6024 continue;
6025 }
6026
6027 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
6028 HadAvailAttr = true;
6029 if (always_unavailable)
6030 *always_unavailable = 1;
6031 if (unavailable_message) {
6032 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6033 }
6034 continue;
6035 }
6036
6037 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
6038 HadAvailAttr = true;
6039 if (N < availability_size) {
6040 availability[N].Platform
6041 = cxstring::createDup(Avail->getPlatform()->getName());
6042 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6043 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6044 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6045 availability[N].Unavailable = Avail->getUnavailable();
6046 availability[N].Message = cxstring::createDup(Avail->getMessage());
6047 }
6048 ++N;
6049 }
6050 }
6051
6052 if (!HadAvailAttr)
6053 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6054 return getCursorPlatformAvailabilityForDecl(
6055 cast<Decl>(EnumConst->getDeclContext()),
6056 always_deprecated,
6057 deprecated_message,
6058 always_unavailable,
6059 unavailable_message,
6060 availability,
6061 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006062
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006063 return N;
6064}
6065
Guy Benyei11169dd2012-12-18 14:30:41 +00006066int clang_getCursorPlatformAvailability(CXCursor cursor,
6067 int *always_deprecated,
6068 CXString *deprecated_message,
6069 int *always_unavailable,
6070 CXString *unavailable_message,
6071 CXPlatformAvailability *availability,
6072 int availability_size) {
6073 if (always_deprecated)
6074 *always_deprecated = 0;
6075 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006076 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006077 if (always_unavailable)
6078 *always_unavailable = 0;
6079 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006080 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006081
Guy Benyei11169dd2012-12-18 14:30:41 +00006082 if (!clang_isDeclaration(cursor.kind))
6083 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006084
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006085 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006086 if (!D)
6087 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006088
6089 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6090 deprecated_message,
6091 always_unavailable,
6092 unavailable_message,
6093 availability,
6094 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006095}
6096
6097void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6098 clang_disposeString(availability->Platform);
6099 clang_disposeString(availability->Message);
6100}
6101
6102CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6103 if (clang_isDeclaration(cursor.kind))
6104 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6105
6106 return CXLanguage_Invalid;
6107}
6108
6109 /// \brief If the given cursor is the "templated" declaration
6110 /// descibing a class or function template, return the class or
6111 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006112static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006113 if (!D)
6114 return 0;
6115
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006116 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006117 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6118 return FunTmpl;
6119
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006120 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006121 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6122 return ClassTmpl;
6123
6124 return D;
6125}
6126
6127CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6128 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006129 if (const Decl *D = getCursorDecl(cursor)) {
6130 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006131 if (!DC)
6132 return clang_getNullCursor();
6133
6134 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6135 getCursorTU(cursor));
6136 }
6137 }
6138
6139 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006140 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006141 return MakeCXCursor(D, getCursorTU(cursor));
6142 }
6143
6144 return clang_getNullCursor();
6145}
6146
6147CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6148 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006149 if (const Decl *D = getCursorDecl(cursor)) {
6150 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006151 if (!DC)
6152 return clang_getNullCursor();
6153
6154 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6155 getCursorTU(cursor));
6156 }
6157 }
6158
6159 // FIXME: Note that we can't easily compute the lexical context of a
6160 // statement or expression, so we return nothing.
6161 return clang_getNullCursor();
6162}
6163
6164CXFile clang_getIncludedFile(CXCursor cursor) {
6165 if (cursor.kind != CXCursor_InclusionDirective)
6166 return 0;
6167
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006168 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006169 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006170}
6171
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006172unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6173 if (C.kind != CXCursor_ObjCPropertyDecl)
6174 return CXObjCPropertyAttr_noattr;
6175
6176 unsigned Result = CXObjCPropertyAttr_noattr;
6177 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6178 ObjCPropertyDecl::PropertyAttributeKind Attr =
6179 PD->getPropertyAttributesAsWritten();
6180
6181#define SET_CXOBJCPROP_ATTR(A) \
6182 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6183 Result |= CXObjCPropertyAttr_##A
6184 SET_CXOBJCPROP_ATTR(readonly);
6185 SET_CXOBJCPROP_ATTR(getter);
6186 SET_CXOBJCPROP_ATTR(assign);
6187 SET_CXOBJCPROP_ATTR(readwrite);
6188 SET_CXOBJCPROP_ATTR(retain);
6189 SET_CXOBJCPROP_ATTR(copy);
6190 SET_CXOBJCPROP_ATTR(nonatomic);
6191 SET_CXOBJCPROP_ATTR(setter);
6192 SET_CXOBJCPROP_ATTR(atomic);
6193 SET_CXOBJCPROP_ATTR(weak);
6194 SET_CXOBJCPROP_ATTR(strong);
6195 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6196#undef SET_CXOBJCPROP_ATTR
6197
6198 return Result;
6199}
6200
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006201unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6202 if (!clang_isDeclaration(C.kind))
6203 return CXObjCDeclQualifier_None;
6204
6205 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6206 const Decl *D = getCursorDecl(C);
6207 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6208 QT = MD->getObjCDeclQualifier();
6209 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6210 QT = PD->getObjCDeclQualifier();
6211 if (QT == Decl::OBJC_TQ_None)
6212 return CXObjCDeclQualifier_None;
6213
6214 unsigned Result = CXObjCDeclQualifier_None;
6215 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6216 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6217 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6218 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6219 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6220 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6221
6222 return Result;
6223}
6224
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006225unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6226 if (!clang_isDeclaration(C.kind))
6227 return 0;
6228
6229 const Decl *D = getCursorDecl(C);
6230 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6231 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6232 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6233 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6234
6235 return 0;
6236}
6237
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006238unsigned clang_Cursor_isVariadic(CXCursor C) {
6239 if (!clang_isDeclaration(C.kind))
6240 return 0;
6241
6242 const Decl *D = getCursorDecl(C);
6243 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6244 return FD->isVariadic();
6245 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6246 return MD->isVariadic();
6247
6248 return 0;
6249}
6250
Guy Benyei11169dd2012-12-18 14:30:41 +00006251CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6252 if (!clang_isDeclaration(C.kind))
6253 return clang_getNullRange();
6254
6255 const Decl *D = getCursorDecl(C);
6256 ASTContext &Context = getCursorContext(C);
6257 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6258 if (!RC)
6259 return clang_getNullRange();
6260
6261 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6262}
6263
6264CXString clang_Cursor_getRawCommentText(CXCursor C) {
6265 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006266 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006267
6268 const Decl *D = getCursorDecl(C);
6269 ASTContext &Context = getCursorContext(C);
6270 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6271 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6272 StringRef();
6273
6274 // Don't duplicate the string because RawText points directly into source
6275 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006276 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006277}
6278
6279CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6280 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006281 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006282
6283 const Decl *D = getCursorDecl(C);
6284 const ASTContext &Context = getCursorContext(C);
6285 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6286
6287 if (RC) {
6288 StringRef BriefText = RC->getBriefText(Context);
6289
6290 // Don't duplicate the string because RawComment ensures that this memory
6291 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006292 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006293 }
6294
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006295 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006296}
6297
6298CXComment clang_Cursor_getParsedComment(CXCursor C) {
6299 if (!clang_isDeclaration(C.kind))
6300 return cxcomment::createCXComment(NULL, NULL);
6301
6302 const Decl *D = getCursorDecl(C);
6303 const ASTContext &Context = getCursorContext(C);
6304 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6305
6306 return cxcomment::createCXComment(FC, getCursorTU(C));
6307}
6308
6309CXModule clang_Cursor_getModule(CXCursor C) {
6310 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006311 if (const ImportDecl *ImportD =
6312 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006313 return ImportD->getImportedModule();
6314 }
6315
6316 return 0;
6317}
6318
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006319CXFile clang_Module_getASTFile(CXModule CXMod) {
6320 if (!CXMod)
6321 return 0;
6322 Module *Mod = static_cast<Module*>(CXMod);
6323 return const_cast<FileEntry *>(Mod->getASTFile());
6324}
6325
Guy Benyei11169dd2012-12-18 14:30:41 +00006326CXModule clang_Module_getParent(CXModule CXMod) {
6327 if (!CXMod)
6328 return 0;
6329 Module *Mod = static_cast<Module*>(CXMod);
6330 return Mod->Parent;
6331}
6332
6333CXString clang_Module_getName(CXModule CXMod) {
6334 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006335 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006336 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006337 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006338}
6339
6340CXString clang_Module_getFullName(CXModule CXMod) {
6341 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006342 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006343 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006344 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006345}
6346
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006347unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6348 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006349 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006350 LOG_BAD_TU(TU);
6351 return 0;
6352 }
6353 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006354 return 0;
6355 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006356 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6357 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6358 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006359}
6360
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006361CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6362 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006363 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006364 LOG_BAD_TU(TU);
6365 return 0;
6366 }
6367 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006368 return 0;
6369 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006370 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006371
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006372 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6373 if (Index < TopHeaders.size())
6374 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006375
6376 return 0;
6377}
6378
6379} // end: extern "C"
6380
6381//===----------------------------------------------------------------------===//
6382// C++ AST instrospection.
6383//===----------------------------------------------------------------------===//
6384
6385extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006386unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6387 if (!clang_isDeclaration(C.kind))
6388 return 0;
6389
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006390 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006391 const CXXMethodDecl *Method =
6392 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006393 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6394}
6395
Guy Benyei11169dd2012-12-18 14:30:41 +00006396unsigned clang_CXXMethod_isStatic(CXCursor C) {
6397 if (!clang_isDeclaration(C.kind))
6398 return 0;
6399
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006400 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006401 const CXXMethodDecl *Method =
6402 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006403 return (Method && Method->isStatic()) ? 1 : 0;
6404}
6405
6406unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6407 if (!clang_isDeclaration(C.kind))
6408 return 0;
6409
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006410 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006411 const CXXMethodDecl *Method =
6412 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006413 return (Method && Method->isVirtual()) ? 1 : 0;
6414}
6415} // end: extern "C"
6416
6417//===----------------------------------------------------------------------===//
6418// Attribute introspection.
6419//===----------------------------------------------------------------------===//
6420
6421extern "C" {
6422CXType clang_getIBOutletCollectionType(CXCursor C) {
6423 if (C.kind != CXCursor_IBOutletCollectionAttr)
6424 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6425
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006426 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006427 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6428
6429 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6430}
6431} // end: extern "C"
6432
6433//===----------------------------------------------------------------------===//
6434// Inspecting memory usage.
6435//===----------------------------------------------------------------------===//
6436
6437typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6438
6439static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6440 enum CXTUResourceUsageKind k,
6441 unsigned long amount) {
6442 CXTUResourceUsageEntry entry = { k, amount };
6443 entries.push_back(entry);
6444}
6445
6446extern "C" {
6447
6448const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6449 const char *str = "";
6450 switch (kind) {
6451 case CXTUResourceUsage_AST:
6452 str = "ASTContext: expressions, declarations, and types";
6453 break;
6454 case CXTUResourceUsage_Identifiers:
6455 str = "ASTContext: identifiers";
6456 break;
6457 case CXTUResourceUsage_Selectors:
6458 str = "ASTContext: selectors";
6459 break;
6460 case CXTUResourceUsage_GlobalCompletionResults:
6461 str = "Code completion: cached global results";
6462 break;
6463 case CXTUResourceUsage_SourceManagerContentCache:
6464 str = "SourceManager: content cache allocator";
6465 break;
6466 case CXTUResourceUsage_AST_SideTables:
6467 str = "ASTContext: side tables";
6468 break;
6469 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6470 str = "SourceManager: malloc'ed memory buffers";
6471 break;
6472 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6473 str = "SourceManager: mmap'ed memory buffers";
6474 break;
6475 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6476 str = "ExternalASTSource: malloc'ed memory buffers";
6477 break;
6478 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6479 str = "ExternalASTSource: mmap'ed memory buffers";
6480 break;
6481 case CXTUResourceUsage_Preprocessor:
6482 str = "Preprocessor: malloc'ed memory";
6483 break;
6484 case CXTUResourceUsage_PreprocessingRecord:
6485 str = "Preprocessor: PreprocessingRecord";
6486 break;
6487 case CXTUResourceUsage_SourceManager_DataStructures:
6488 str = "SourceManager: data structures and tables";
6489 break;
6490 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6491 str = "Preprocessor: header search tables";
6492 break;
6493 }
6494 return str;
6495}
6496
6497CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006498 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006499 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006500 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6501 return usage;
6502 }
6503
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006504 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006505 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6506 ASTContext &astContext = astUnit->getASTContext();
6507
6508 // How much memory is used by AST nodes and types?
6509 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6510 (unsigned long) astContext.getASTAllocatedMemory());
6511
6512 // How much memory is used by identifiers?
6513 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6514 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6515
6516 // How much memory is used for selectors?
6517 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6518 (unsigned long) astContext.Selectors.getTotalMemory());
6519
6520 // How much memory is used by ASTContext's side tables?
6521 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6522 (unsigned long) astContext.getSideTableAllocatedMemory());
6523
6524 // How much memory is used for caching global code completion results?
6525 unsigned long completionBytes = 0;
6526 if (GlobalCodeCompletionAllocator *completionAllocator =
6527 astUnit->getCachedCompletionAllocator().getPtr()) {
6528 completionBytes = completionAllocator->getTotalMemory();
6529 }
6530 createCXTUResourceUsageEntry(*entries,
6531 CXTUResourceUsage_GlobalCompletionResults,
6532 completionBytes);
6533
6534 // How much memory is being used by SourceManager's content cache?
6535 createCXTUResourceUsageEntry(*entries,
6536 CXTUResourceUsage_SourceManagerContentCache,
6537 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6538
6539 // How much memory is being used by the MemoryBuffer's in SourceManager?
6540 const SourceManager::MemoryBufferSizes &srcBufs =
6541 astUnit->getSourceManager().getMemoryBufferSizes();
6542
6543 createCXTUResourceUsageEntry(*entries,
6544 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6545 (unsigned long) srcBufs.malloc_bytes);
6546 createCXTUResourceUsageEntry(*entries,
6547 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6548 (unsigned long) srcBufs.mmap_bytes);
6549 createCXTUResourceUsageEntry(*entries,
6550 CXTUResourceUsage_SourceManager_DataStructures,
6551 (unsigned long) astContext.getSourceManager()
6552 .getDataStructureSizes());
6553
6554 // How much memory is being used by the ExternalASTSource?
6555 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6556 const ExternalASTSource::MemoryBufferSizes &sizes =
6557 esrc->getMemoryBufferSizes();
6558
6559 createCXTUResourceUsageEntry(*entries,
6560 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6561 (unsigned long) sizes.malloc_bytes);
6562 createCXTUResourceUsageEntry(*entries,
6563 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6564 (unsigned long) sizes.mmap_bytes);
6565 }
6566
6567 // How much memory is being used by the Preprocessor?
6568 Preprocessor &pp = astUnit->getPreprocessor();
6569 createCXTUResourceUsageEntry(*entries,
6570 CXTUResourceUsage_Preprocessor,
6571 pp.getTotalMemory());
6572
6573 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6574 createCXTUResourceUsageEntry(*entries,
6575 CXTUResourceUsage_PreprocessingRecord,
6576 pRec->getTotalMemory());
6577 }
6578
6579 createCXTUResourceUsageEntry(*entries,
6580 CXTUResourceUsage_Preprocessor_HeaderSearch,
6581 pp.getHeaderSearchInfo().getTotalMemory());
6582
6583 CXTUResourceUsage usage = { (void*) entries.get(),
6584 (unsigned) entries->size(),
6585 entries->size() ? &(*entries)[0] : 0 };
6586 entries.take();
6587 return usage;
6588}
6589
6590void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6591 if (usage.data)
6592 delete (MemUsageEntries*) usage.data;
6593}
6594
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006595CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6596 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006597 skipped->count = 0;
6598 skipped->ranges = 0;
6599
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006600 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006601 LOG_BAD_TU(TU);
6602 return skipped;
6603 }
6604
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006605 if (!file)
6606 return skipped;
6607
6608 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6609 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6610 if (!ppRec)
6611 return skipped;
6612
6613 ASTContext &Ctx = astUnit->getASTContext();
6614 SourceManager &sm = Ctx.getSourceManager();
6615 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6616 FileID wantedFileID = sm.translateFile(fileEntry);
6617
6618 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6619 std::vector<SourceRange> wantedRanges;
6620 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6621 i != ei; ++i) {
6622 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6623 wantedRanges.push_back(*i);
6624 }
6625
6626 skipped->count = wantedRanges.size();
6627 skipped->ranges = new CXSourceRange[skipped->count];
6628 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6629 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6630
6631 return skipped;
6632}
6633
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006634void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6635 if (ranges) {
6636 delete[] ranges->ranges;
6637 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006638 }
6639}
6640
Guy Benyei11169dd2012-12-18 14:30:41 +00006641} // end extern "C"
6642
6643void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6644 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6645 for (unsigned I = 0; I != Usage.numEntries; ++I)
6646 fprintf(stderr, " %s: %lu\n",
6647 clang_getTUResourceUsageName(Usage.entries[I].kind),
6648 Usage.entries[I].amount);
6649
6650 clang_disposeCXTUResourceUsage(Usage);
6651}
6652
6653//===----------------------------------------------------------------------===//
6654// Misc. utility functions.
6655//===----------------------------------------------------------------------===//
6656
6657/// Default to using an 8 MB stack size on "safety" threads.
6658static unsigned SafetyStackThreadSize = 8 << 20;
6659
6660namespace clang {
6661
6662bool RunSafely(llvm::CrashRecoveryContext &CRC,
6663 void (*Fn)(void*), void *UserData,
6664 unsigned Size) {
6665 if (!Size)
6666 Size = GetSafetyThreadStackSize();
6667 if (Size)
6668 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6669 return CRC.RunSafely(Fn, UserData);
6670}
6671
6672unsigned GetSafetyThreadStackSize() {
6673 return SafetyStackThreadSize;
6674}
6675
6676void SetSafetyThreadStackSize(unsigned Value) {
6677 SafetyStackThreadSize = Value;
6678}
6679
6680}
6681
6682void clang::setThreadBackgroundPriority() {
6683 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6684 return;
6685
6686 // FIXME: Move to llvm/Support and make it cross-platform.
6687#ifdef __APPLE__
6688 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6689#endif
6690}
6691
6692void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6693 if (!Unit)
6694 return;
6695
6696 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6697 DEnd = Unit->stored_diag_end();
6698 D != DEnd; ++D) {
6699 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6700 CXString Msg = clang_formatDiagnostic(&Diag,
6701 clang_defaultDiagnosticDisplayOptions());
6702 fprintf(stderr, "%s\n", clang_getCString(Msg));
6703 clang_disposeString(Msg);
6704 }
6705#ifdef LLVM_ON_WIN32
6706 // On Windows, force a flush, since there may be multiple copies of
6707 // stderr and stdout in the file system, all with different buffers
6708 // but writing to the same device.
6709 fflush(stderr);
6710#endif
6711}
6712
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006713MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6714 SourceLocation MacroDefLoc,
6715 CXTranslationUnit TU){
6716 if (MacroDefLoc.isInvalid() || !TU)
6717 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006718 if (!II.hadMacroDefinition())
6719 return 0;
6720
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006721 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006722 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006723 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006724 if (MD) {
6725 for (MacroDirective::DefInfo
6726 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6727 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6728 return Def.getMacroInfo();
6729 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006730 }
6731
6732 return 0;
6733}
6734
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006735const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6736 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006737 if (!MacroDef || !TU)
6738 return 0;
6739 const IdentifierInfo *II = MacroDef->getName();
6740 if (!II)
6741 return 0;
6742
6743 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6744}
6745
6746MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6747 const Token &Tok,
6748 CXTranslationUnit TU) {
6749 if (!MI || !TU)
6750 return 0;
6751 if (Tok.isNot(tok::raw_identifier))
6752 return 0;
6753
6754 if (MI->getNumTokens() == 0)
6755 return 0;
6756 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6757 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006758 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006759
6760 // Check that the token is inside the definition and not its argument list.
6761 SourceManager &SM = Unit->getSourceManager();
6762 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6763 return 0;
6764 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6765 return 0;
6766
6767 Preprocessor &PP = Unit->getPreprocessor();
6768 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6769 if (!PPRec)
6770 return 0;
6771
6772 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6773 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6774 if (!II.hadMacroDefinition())
6775 return 0;
6776
6777 // Check that the identifier is not one of the macro arguments.
6778 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6779 return 0;
6780
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006781 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6782 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006783 return 0;
6784
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006785 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006786}
6787
6788MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6789 SourceLocation Loc,
6790 CXTranslationUnit TU) {
6791 if (Loc.isInvalid() || !MI || !TU)
6792 return 0;
6793
6794 if (MI->getNumTokens() == 0)
6795 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006796 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006797 Preprocessor &PP = Unit->getPreprocessor();
6798 if (!PP.getPreprocessingRecord())
6799 return 0;
6800 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6801 Token Tok;
6802 if (PP.getRawToken(Loc, Tok))
6803 return 0;
6804
6805 return checkForMacroInMacroDefinition(MI, Tok, TU);
6806}
6807
Guy Benyei11169dd2012-12-18 14:30:41 +00006808extern "C" {
6809
6810CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006811 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006812}
6813
6814} // end: extern "C"
6815
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006816Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6817 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006818 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006819 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006820 if (Unit->isMainFileAST())
6821 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006822 return *this;
6823 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006824 } else {
6825 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006826 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006827 return *this;
6828}
6829
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006830Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6831 *this << FE->getName();
6832 return *this;
6833}
6834
6835Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6836 CXString cursorName = clang_getCursorDisplayName(cursor);
6837 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6838 clang_disposeString(cursorName);
6839 return *this;
6840}
6841
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006842Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6843 CXFile File;
6844 unsigned Line, Column;
6845 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6846 CXString FileName = clang_getFileName(File);
6847 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6848 clang_disposeString(FileName);
6849 return *this;
6850}
6851
6852Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6853 CXSourceLocation BLoc = clang_getRangeStart(range);
6854 CXSourceLocation ELoc = clang_getRangeEnd(range);
6855
6856 CXFile BFile;
6857 unsigned BLine, BColumn;
6858 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6859
6860 CXFile EFile;
6861 unsigned ELine, EColumn;
6862 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6863
6864 CXString BFileName = clang_getFileName(BFile);
6865 if (BFile == EFile) {
6866 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6867 BLine, BColumn, ELine, EColumn);
6868 } else {
6869 CXString EFileName = clang_getFileName(EFile);
6870 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6871 BLine, BColumn)
6872 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6873 ELine, EColumn);
6874 clang_disposeString(EFileName);
6875 }
6876 clang_disposeString(BFileName);
6877 return *this;
6878}
6879
6880Logger &cxindex::Logger::operator<<(CXString Str) {
6881 *this << clang_getCString(Str);
6882 return *this;
6883}
6884
6885Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6886 LogOS << Fmt;
6887 return *this;
6888}
6889
6890cxindex::Logger::~Logger() {
6891 LogOS.flush();
6892
6893 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6894
6895 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6896
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006897 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006898 OS << "[libclang:" << Name << ':';
6899
6900 // FIXME: Portability.
6901#if HAVE_PTHREAD_H && __APPLE__
6902 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6903 OS << tid << ':';
6904#endif
6905
6906 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6907 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6908 OS << Msg.str() << '\n';
6909
6910 if (Trace) {
6911 llvm::sys::PrintStackTrace(stderr);
6912 OS << "--------------------------------------------------\n";
6913 }
6914}