blob: d8cca44a0ea0e86ca59a0742b29c563dd4159077 [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);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002824 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002825 assert((TU && Result == CXError_Success) ||
2826 (!TU && Result != CXError_Success));
2827 return TU;
2828}
2829
2830enum CXErrorCode clang_parseTranslationUnit2(
2831 CXIndex CIdx,
2832 const char *source_filename,
2833 const char *const *command_line_args,
2834 int num_command_line_args,
2835 struct CXUnsavedFile *unsaved_files,
2836 unsigned num_unsaved_files,
2837 unsigned options,
2838 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002839 LOG_FUNC_SECTION {
2840 *Log << source_filename << ": ";
2841 for (int i = 0; i != num_command_line_args; ++i)
2842 *Log << command_line_args[i] << " ";
2843 }
2844
Guy Benyei11169dd2012-12-18 14:30:41 +00002845 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2846 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002847 num_unsaved_files, options, out_TU,
2848 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002849 llvm::CrashRecoveryContext CRC;
2850
2851 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2852 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2853 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2854 fprintf(stderr, " 'command_line_args' : [");
2855 for (int i = 0; i != num_command_line_args; ++i) {
2856 if (i)
2857 fprintf(stderr, ", ");
2858 fprintf(stderr, "'%s'", command_line_args[i]);
2859 }
2860 fprintf(stderr, "],\n");
2861 fprintf(stderr, " 'unsaved_files' : [");
2862 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2863 if (i)
2864 fprintf(stderr, ", ");
2865 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2866 unsaved_files[i].Length);
2867 }
2868 fprintf(stderr, "],\n");
2869 fprintf(stderr, " 'options' : %d,\n", options);
2870 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002871
2872 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002873 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002874 if (CXTranslationUnit *TU = PTUI.out_TU)
2875 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002876 }
2877
2878 return PTUI.result;
2879}
2880
2881unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2882 return CXSaveTranslationUnit_None;
2883}
2884
2885namespace {
2886
2887struct SaveTranslationUnitInfo {
2888 CXTranslationUnit TU;
2889 const char *FileName;
2890 unsigned options;
2891 CXSaveError result;
2892};
2893
2894}
2895
2896static void clang_saveTranslationUnit_Impl(void *UserData) {
2897 SaveTranslationUnitInfo *STUI =
2898 static_cast<SaveTranslationUnitInfo*>(UserData);
2899
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002900 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002901 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2902 setThreadBackgroundPriority();
2903
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002904 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002905 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2906}
2907
2908int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2909 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002910 LOG_FUNC_SECTION {
2911 *Log << TU << ' ' << FileName;
2912 }
2913
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002914 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002915 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002916 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002917 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002918
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002919 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002920 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2921 if (!CXXUnit->hasSema())
2922 return CXSaveError_InvalidTU;
2923
2924 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2925
2926 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2927 getenv("LIBCLANG_NOTHREADS")) {
2928 clang_saveTranslationUnit_Impl(&STUI);
2929
2930 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2931 PrintLibclangResourceUsage(TU);
2932
2933 return STUI.result;
2934 }
2935
2936 // We have an AST that has invalid nodes due to compiler errors.
2937 // Use a crash recovery thread for protection.
2938
2939 llvm::CrashRecoveryContext CRC;
2940
2941 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2942 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2943 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2944 fprintf(stderr, " 'options' : %d,\n", options);
2945 fprintf(stderr, "}\n");
2946
2947 return CXSaveError_Unknown;
2948
2949 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2950 PrintLibclangResourceUsage(TU);
2951 }
2952
2953 return STUI.result;
2954}
2955
2956void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2957 if (CTUnit) {
2958 // If the translation unit has been marked as unsafe to free, just discard
2959 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002960 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2961 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002962 return;
2963
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002964 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002965 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002966 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2967 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002968 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002969 delete CTUnit;
2970 }
2971}
2972
2973unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2974 return CXReparse_None;
2975}
2976
2977struct ReparseTranslationUnitInfo {
2978 CXTranslationUnit TU;
2979 unsigned num_unsaved_files;
2980 struct CXUnsavedFile *unsaved_files;
2981 unsigned options;
2982 int result;
2983};
2984
2985static void clang_reparseTranslationUnit_Impl(void *UserData) {
2986 ReparseTranslationUnitInfo *RTUI =
2987 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002988 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002989
Guy Benyei11169dd2012-12-18 14:30:41 +00002990 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002991 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2992 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2993 unsigned options = RTUI->options;
2994 (void) options;
2995
2996 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002997 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002998 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002999 RTUI->result = CXError_InvalidArguments;
3000 return;
3001 }
3002 if (unsaved_files == NULL && num_unsaved_files != 0) {
3003 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003004 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003005 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003006
3007 // Reset the associated diagnostics.
3008 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3009 TU->Diagnostics = 0;
3010
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003011 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003012 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3013 setThreadBackgroundPriority();
3014
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003015 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003016 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3017
3018 OwningPtr<std::vector<ASTUnit::RemappedFile> >
3019 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
3020
3021 // Recover resources if we crash before exiting this function.
3022 llvm::CrashRecoveryContextCleanupRegistrar<
3023 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3024
3025 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3026 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3027 const llvm::MemoryBuffer *Buffer
3028 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3029 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3030 Buffer));
3031 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003032
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003033 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003034 RTUI->result = CXError_Success;
3035 else if (isASTReadError(CXXUnit))
3036 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003037}
3038
3039int clang_reparseTranslationUnit(CXTranslationUnit TU,
3040 unsigned num_unsaved_files,
3041 struct CXUnsavedFile *unsaved_files,
3042 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003043 LOG_FUNC_SECTION {
3044 *Log << TU;
3045 }
3046
Guy Benyei11169dd2012-12-18 14:30:41 +00003047 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003048 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003049
3050 if (getenv("LIBCLANG_NOTHREADS")) {
3051 clang_reparseTranslationUnit_Impl(&RTUI);
3052 return RTUI.result;
3053 }
3054
3055 llvm::CrashRecoveryContext CRC;
3056
3057 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3058 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003059 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003060 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003061 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3062 PrintLibclangResourceUsage(TU);
3063
3064 return RTUI.result;
3065}
3066
3067
3068CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003069 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003070 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003071 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003072 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003073
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003074 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003075 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003076}
3077
3078CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003079 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003080 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003081 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003082 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003083
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003084 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003085 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3086}
3087
3088} // end: extern "C"
3089
3090//===----------------------------------------------------------------------===//
3091// CXFile Operations.
3092//===----------------------------------------------------------------------===//
3093
3094extern "C" {
3095CXString clang_getFileName(CXFile SFile) {
3096 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003097 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003098
3099 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003100 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003101}
3102
3103time_t clang_getFileTime(CXFile SFile) {
3104 if (!SFile)
3105 return 0;
3106
3107 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3108 return FEnt->getModificationTime();
3109}
3110
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003111CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003112 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003113 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003114 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003115 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003116
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003117 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003118
3119 FileManager &FMgr = CXXUnit->getFileManager();
3120 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3121}
3122
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003123unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3124 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003125 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003126 LOG_BAD_TU(TU);
3127 return 0;
3128 }
3129
3130 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003131 return 0;
3132
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003133 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003134 FileEntry *FEnt = static_cast<FileEntry *>(file);
3135 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3136 .isFileMultipleIncludeGuarded(FEnt);
3137}
3138
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003139int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3140 if (!file || !outID)
3141 return 1;
3142
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003143 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003144 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3145 outID->data[0] = ID.getDevice();
3146 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003147 outID->data[2] = FEnt->getModificationTime();
3148 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003149}
3150
Guy Benyei11169dd2012-12-18 14:30:41 +00003151} // end: extern "C"
3152
3153//===----------------------------------------------------------------------===//
3154// CXCursor Operations.
3155//===----------------------------------------------------------------------===//
3156
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003157static const Decl *getDeclFromExpr(const Stmt *E) {
3158 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003159 return getDeclFromExpr(CE->getSubExpr());
3160
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003161 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003162 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003163 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003164 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003165 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003166 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003167 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003168 if (PRE->isExplicitProperty())
3169 return PRE->getExplicitProperty();
3170 // It could be messaging both getter and setter as in:
3171 // ++myobj.myprop;
3172 // in which case prefer to associate the setter since it is less obvious
3173 // from inspecting the source that the setter is going to get called.
3174 if (PRE->isMessagingSetter())
3175 return PRE->getImplicitPropertySetter();
3176 return PRE->getImplicitPropertyGetter();
3177 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003178 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003179 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003180 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003181 if (Expr *Src = OVE->getSourceExpr())
3182 return getDeclFromExpr(Src);
3183
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003184 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003185 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003186 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003187 if (!CE->isElidable())
3188 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003189 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003190 return OME->getMethodDecl();
3191
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003192 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003193 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003194 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003195 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3196 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003197 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003198 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3199 isa<ParmVarDecl>(SizeOfPack->getPack()))
3200 return SizeOfPack->getPack();
3201
3202 return 0;
3203}
3204
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003205static SourceLocation getLocationFromExpr(const Expr *E) {
3206 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003207 return getLocationFromExpr(CE->getSubExpr());
3208
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003209 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003210 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003211 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003212 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003213 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003214 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003215 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003216 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003217 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003218 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003219 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003220 return PropRef->getLocation();
3221
3222 return E->getLocStart();
3223}
3224
3225extern "C" {
3226
3227unsigned clang_visitChildren(CXCursor parent,
3228 CXCursorVisitor visitor,
3229 CXClientData client_data) {
3230 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3231 /*VisitPreprocessorLast=*/false);
3232 return CursorVis.VisitChildren(parent);
3233}
3234
3235#ifndef __has_feature
3236#define __has_feature(x) 0
3237#endif
3238#if __has_feature(blocks)
3239typedef enum CXChildVisitResult
3240 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3241
3242static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3243 CXClientData client_data) {
3244 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3245 return block(cursor, parent);
3246}
3247#else
3248// If we are compiled with a compiler that doesn't have native blocks support,
3249// define and call the block manually, so the
3250typedef struct _CXChildVisitResult
3251{
3252 void *isa;
3253 int flags;
3254 int reserved;
3255 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3256 CXCursor);
3257} *CXCursorVisitorBlock;
3258
3259static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3260 CXClientData client_data) {
3261 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3262 return block->invoke(block, cursor, parent);
3263}
3264#endif
3265
3266
3267unsigned clang_visitChildrenWithBlock(CXCursor parent,
3268 CXCursorVisitorBlock block) {
3269 return clang_visitChildren(parent, visitWithBlock, block);
3270}
3271
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003272static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003273 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003274 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003275
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003276 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003277 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003278 if (const ObjCPropertyImplDecl *PropImpl =
3279 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003280 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003281 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003282
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003283 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003284 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003285 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003286
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003287 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003288 }
3289
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003290 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003291 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003292
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003293 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003294 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3295 // and returns different names. NamedDecl returns the class name and
3296 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003297 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003298
3299 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003300 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003301
3302 SmallString<1024> S;
3303 llvm::raw_svector_ostream os(S);
3304 ND->printName(os);
3305
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003306 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003307}
3308
3309CXString clang_getCursorSpelling(CXCursor C) {
3310 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003311 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003312
3313 if (clang_isReference(C.kind)) {
3314 switch (C.kind) {
3315 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003316 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003317 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003318 }
3319 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003320 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003321 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003322 }
3323 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003324 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003325 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003326 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003327 }
3328 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003329 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003330 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003331 }
3332 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003333 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 assert(Type && "Missing type decl");
3335
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003336 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003337 getAsString());
3338 }
3339 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003340 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003341 assert(Template && "Missing template decl");
3342
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003343 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003344 }
3345
3346 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003347 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 assert(NS && "Missing namespace decl");
3349
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003350 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003351 }
3352
3353 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003354 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003355 assert(Field && "Missing member decl");
3356
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003357 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003358 }
3359
3360 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003361 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003362 assert(Label && "Missing label");
3363
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003364 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003365 }
3366
3367 case CXCursor_OverloadedDeclRef: {
3368 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003369 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3370 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003371 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003372 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003374 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003375 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003376 OverloadedTemplateStorage *Ovl
3377 = Storage.get<OverloadedTemplateStorage*>();
3378 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003379 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003380 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003381 }
3382
3383 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003384 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003385 assert(Var && "Missing variable decl");
3386
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003387 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003388 }
3389
3390 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003391 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003392 }
3393 }
3394
3395 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003396 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003397 if (D)
3398 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003399 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003400 }
3401
3402 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003403 const Stmt *S = getCursorStmt(C);
3404 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003405 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003406
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003407 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003408 }
3409
3410 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003411 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003412 ->getNameStart());
3413
3414 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003415 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003416 ->getNameStart());
3417
3418 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003419 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003420
3421 if (clang_isDeclaration(C.kind))
3422 return getDeclSpelling(getCursorDecl(C));
3423
3424 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003425 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003426 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003427 }
3428
3429 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003430 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003431 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003432 }
3433
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003434 if (C.kind == CXCursor_PackedAttr) {
3435 return cxstring::createRef("packed");
3436 }
3437
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003438 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003439}
3440
3441CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3442 unsigned pieceIndex,
3443 unsigned options) {
3444 if (clang_Cursor_isNull(C))
3445 return clang_getNullRange();
3446
3447 ASTContext &Ctx = getCursorContext(C);
3448
3449 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003450 const Stmt *S = getCursorStmt(C);
3451 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003452 if (pieceIndex > 0)
3453 return clang_getNullRange();
3454 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3455 }
3456
3457 return clang_getNullRange();
3458 }
3459
3460 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003461 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003462 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3463 if (pieceIndex >= ME->getNumSelectorLocs())
3464 return clang_getNullRange();
3465 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3466 }
3467 }
3468
3469 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3470 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003471 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003472 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3473 if (pieceIndex >= MD->getNumSelectorLocs())
3474 return clang_getNullRange();
3475 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3476 }
3477 }
3478
3479 if (C.kind == CXCursor_ObjCCategoryDecl ||
3480 C.kind == CXCursor_ObjCCategoryImplDecl) {
3481 if (pieceIndex > 0)
3482 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003483 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003484 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3485 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003486 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003487 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3488 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3489 }
3490
3491 if (C.kind == CXCursor_ModuleImportDecl) {
3492 if (pieceIndex > 0)
3493 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003494 if (const ImportDecl *ImportD =
3495 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003496 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3497 if (!Locs.empty())
3498 return cxloc::translateSourceRange(Ctx,
3499 SourceRange(Locs.front(), Locs.back()));
3500 }
3501 return clang_getNullRange();
3502 }
3503
3504 // FIXME: A CXCursor_InclusionDirective should give the location of the
3505 // filename, but we don't keep track of this.
3506
3507 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3508 // but we don't keep track of this.
3509
3510 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3511 // but we don't keep track of this.
3512
3513 // Default handling, give the location of the cursor.
3514
3515 if (pieceIndex > 0)
3516 return clang_getNullRange();
3517
3518 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3519 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3520 return cxloc::translateSourceRange(Ctx, Loc);
3521}
3522
3523CXString clang_getCursorDisplayName(CXCursor C) {
3524 if (!clang_isDeclaration(C.kind))
3525 return clang_getCursorSpelling(C);
3526
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003527 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003528 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003529 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003530
3531 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003532 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003533 D = FunTmpl->getTemplatedDecl();
3534
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003535 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003536 SmallString<64> Str;
3537 llvm::raw_svector_ostream OS(Str);
3538 OS << *Function;
3539 if (Function->getPrimaryTemplate())
3540 OS << "<>";
3541 OS << "(";
3542 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3543 if (I)
3544 OS << ", ";
3545 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3546 }
3547
3548 if (Function->isVariadic()) {
3549 if (Function->getNumParams())
3550 OS << ", ";
3551 OS << "...";
3552 }
3553 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003554 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003555 }
3556
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003557 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003558 SmallString<64> Str;
3559 llvm::raw_svector_ostream OS(Str);
3560 OS << *ClassTemplate;
3561 OS << "<";
3562 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3563 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3564 if (I)
3565 OS << ", ";
3566
3567 NamedDecl *Param = Params->getParam(I);
3568 if (Param->getIdentifier()) {
3569 OS << Param->getIdentifier()->getName();
3570 continue;
3571 }
3572
3573 // There is no parameter name, which makes this tricky. Try to come up
3574 // with something useful that isn't too long.
3575 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3576 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3577 else if (NonTypeTemplateParmDecl *NTTP
3578 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3579 OS << NTTP->getType().getAsString(Policy);
3580 else
3581 OS << "template<...> class";
3582 }
3583
3584 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003585 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003586 }
3587
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003588 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003589 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3590 // If the type was explicitly written, use that.
3591 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003592 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003593
Benjamin Kramer9170e912013-02-22 15:46:01 +00003594 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003595 llvm::raw_svector_ostream OS(Str);
3596 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003597 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003598 ClassSpec->getTemplateArgs().data(),
3599 ClassSpec->getTemplateArgs().size(),
3600 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003601 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003602 }
3603
3604 return clang_getCursorSpelling(C);
3605}
3606
3607CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3608 switch (Kind) {
3609 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003610 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003611 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003612 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003613 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003614 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003615 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003616 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003617 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003618 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003619 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003620 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003621 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003622 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003624 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003626 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003628 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003630 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003632 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003633 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003634 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003636 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003638 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003639 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003640 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003642 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003643 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003644 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003646 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003648 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003650 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003652 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003654 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003656 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003658 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003660 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003662 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003664 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003666 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003668 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003670 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003672 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003737 case CXCursor_ObjCSelfExpr:
3738 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003855 case CXCursor_PackedAttr:
3856 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003905 case CXCursor_OMPParallelDirective:
3906 return cxstring::createRef("OMPParallelDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 }
3908
3909 llvm_unreachable("Unhandled CXCursorKind");
3910}
3911
3912struct GetCursorData {
3913 SourceLocation TokenBeginLoc;
3914 bool PointsAtMacroArgExpansion;
3915 bool VisitedObjCPropertyImplDecl;
3916 SourceLocation VisitedDeclaratorDeclStartLoc;
3917 CXCursor &BestCursor;
3918
3919 GetCursorData(SourceManager &SM,
3920 SourceLocation tokenBegin, CXCursor &outputCursor)
3921 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3922 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3923 VisitedObjCPropertyImplDecl = false;
3924 }
3925};
3926
3927static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3928 CXCursor parent,
3929 CXClientData client_data) {
3930 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3931 CXCursor *BestCursor = &Data->BestCursor;
3932
3933 // If we point inside a macro argument we should provide info of what the
3934 // token is so use the actual cursor, don't replace it with a macro expansion
3935 // cursor.
3936 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3937 return CXChildVisit_Recurse;
3938
3939 if (clang_isDeclaration(cursor.kind)) {
3940 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003941 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003942 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3943 if (MD->isImplicit())
3944 return CXChildVisit_Break;
3945
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003946 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3948 // Check that when we have multiple @class references in the same line,
3949 // that later ones do not override the previous ones.
3950 // If we have:
3951 // @class Foo, Bar;
3952 // source ranges for both start at '@', so 'Bar' will end up overriding
3953 // 'Foo' even though the cursor location was at 'Foo'.
3954 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3955 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003956 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3958 if (PrevID != ID &&
3959 !PrevID->isThisDeclarationADefinition() &&
3960 !ID->isThisDeclarationADefinition())
3961 return CXChildVisit_Break;
3962 }
3963
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003964 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3966 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3967 // Check that when we have multiple declarators in the same line,
3968 // that later ones do not override the previous ones.
3969 // If we have:
3970 // int Foo, Bar;
3971 // source ranges for both start at 'int', so 'Bar' will end up overriding
3972 // 'Foo' even though the cursor location was at 'Foo'.
3973 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3974 return CXChildVisit_Break;
3975 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3976
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003977 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3979 (void)PropImp;
3980 // Check that when we have multiple @synthesize in the same line,
3981 // that later ones do not override the previous ones.
3982 // If we have:
3983 // @synthesize Foo, Bar;
3984 // source ranges for both start at '@', so 'Bar' will end up overriding
3985 // 'Foo' even though the cursor location was at 'Foo'.
3986 if (Data->VisitedObjCPropertyImplDecl)
3987 return CXChildVisit_Break;
3988 Data->VisitedObjCPropertyImplDecl = true;
3989 }
3990 }
3991
3992 if (clang_isExpression(cursor.kind) &&
3993 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003994 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003995 // Avoid having the cursor of an expression replace the declaration cursor
3996 // when the expression source range overlaps the declaration range.
3997 // This can happen for C++ constructor expressions whose range generally
3998 // include the variable declaration, e.g.:
3999 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4000 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4001 D->getLocation() == Data->TokenBeginLoc)
4002 return CXChildVisit_Break;
4003 }
4004 }
4005
4006 // If our current best cursor is the construction of a temporary object,
4007 // don't replace that cursor with a type reference, because we want
4008 // clang_getCursor() to point at the constructor.
4009 if (clang_isExpression(BestCursor->kind) &&
4010 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4011 cursor.kind == CXCursor_TypeRef) {
4012 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4013 // as having the actual point on the type reference.
4014 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4015 return CXChildVisit_Recurse;
4016 }
4017
4018 *BestCursor = cursor;
4019 return CXChildVisit_Recurse;
4020}
4021
4022CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004023 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004024 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004025 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004026 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004027
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004028 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004029 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4030
4031 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4032 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4033
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004034 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 CXFile SearchFile;
4036 unsigned SearchLine, SearchColumn;
4037 CXFile ResultFile;
4038 unsigned ResultLine, ResultColumn;
4039 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4040 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4041 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4042
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004043 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4044 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004045 &ResultColumn, 0);
4046 SearchFileName = clang_getFileName(SearchFile);
4047 ResultFileName = clang_getFileName(ResultFile);
4048 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4049 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004050 *Log << llvm::format("(%s:%d:%d) = %s",
4051 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4052 clang_getCString(KindSpelling))
4053 << llvm::format("(%s:%d:%d):%s%s",
4054 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4055 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 clang_disposeString(SearchFileName);
4057 clang_disposeString(ResultFileName);
4058 clang_disposeString(KindSpelling);
4059 clang_disposeString(USR);
4060
4061 CXCursor Definition = clang_getCursorDefinition(Result);
4062 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4063 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4064 CXString DefinitionKindSpelling
4065 = clang_getCursorKindSpelling(Definition.kind);
4066 CXFile DefinitionFile;
4067 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004068 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 &DefinitionLine, &DefinitionColumn, 0);
4070 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004071 *Log << llvm::format(" -> %s(%s:%d:%d)",
4072 clang_getCString(DefinitionKindSpelling),
4073 clang_getCString(DefinitionFileName),
4074 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004075 clang_disposeString(DefinitionFileName);
4076 clang_disposeString(DefinitionKindSpelling);
4077 }
4078 }
4079
4080 return Result;
4081}
4082
4083CXCursor clang_getNullCursor(void) {
4084 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4085}
4086
4087unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004088 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4089 // can't set consistently. For example, when visiting a DeclStmt we will set
4090 // it but we don't set it on the result of clang_getCursorDefinition for
4091 // a reference of the same declaration.
4092 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4093 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4094 // to provide that kind of info.
4095 if (clang_isDeclaration(X.kind))
4096 X.data[1] = 0;
4097 if (clang_isDeclaration(Y.kind))
4098 Y.data[1] = 0;
4099
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 return X == Y;
4101}
4102
4103unsigned clang_hashCursor(CXCursor C) {
4104 unsigned Index = 0;
4105 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4106 Index = 1;
4107
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004108 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004109 std::make_pair(C.kind, C.data[Index]));
4110}
4111
4112unsigned clang_isInvalid(enum CXCursorKind K) {
4113 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4114}
4115
4116unsigned clang_isDeclaration(enum CXCursorKind K) {
4117 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4118 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4119}
4120
4121unsigned clang_isReference(enum CXCursorKind K) {
4122 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4123}
4124
4125unsigned clang_isExpression(enum CXCursorKind K) {
4126 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4127}
4128
4129unsigned clang_isStatement(enum CXCursorKind K) {
4130 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4131}
4132
4133unsigned clang_isAttribute(enum CXCursorKind K) {
4134 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4135}
4136
4137unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4138 return K == CXCursor_TranslationUnit;
4139}
4140
4141unsigned clang_isPreprocessing(enum CXCursorKind K) {
4142 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4143}
4144
4145unsigned clang_isUnexposed(enum CXCursorKind K) {
4146 switch (K) {
4147 case CXCursor_UnexposedDecl:
4148 case CXCursor_UnexposedExpr:
4149 case CXCursor_UnexposedStmt:
4150 case CXCursor_UnexposedAttr:
4151 return true;
4152 default:
4153 return false;
4154 }
4155}
4156
4157CXCursorKind clang_getCursorKind(CXCursor C) {
4158 return C.kind;
4159}
4160
4161CXSourceLocation clang_getCursorLocation(CXCursor C) {
4162 if (clang_isReference(C.kind)) {
4163 switch (C.kind) {
4164 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004165 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004166 = getCursorObjCSuperClassRef(C);
4167 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4168 }
4169
4170 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004171 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004172 = getCursorObjCProtocolRef(C);
4173 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4174 }
4175
4176 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004177 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004178 = getCursorObjCClassRef(C);
4179 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4180 }
4181
4182 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004183 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004184 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4185 }
4186
4187 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004188 std::pair<const TemplateDecl *, SourceLocation> P =
4189 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4191 }
4192
4193 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004194 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4196 }
4197
4198 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004199 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4201 }
4202
4203 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004204 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4206 }
4207
4208 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004209 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 if (!BaseSpec)
4211 return clang_getNullLocation();
4212
4213 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4214 return cxloc::translateSourceLocation(getCursorContext(C),
4215 TSInfo->getTypeLoc().getBeginLoc());
4216
4217 return cxloc::translateSourceLocation(getCursorContext(C),
4218 BaseSpec->getLocStart());
4219 }
4220
4221 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004222 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004223 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4224 }
4225
4226 case CXCursor_OverloadedDeclRef:
4227 return cxloc::translateSourceLocation(getCursorContext(C),
4228 getCursorOverloadedDeclRef(C).second);
4229
4230 default:
4231 // FIXME: Need a way to enumerate all non-reference cases.
4232 llvm_unreachable("Missed a reference kind");
4233 }
4234 }
4235
4236 if (clang_isExpression(C.kind))
4237 return cxloc::translateSourceLocation(getCursorContext(C),
4238 getLocationFromExpr(getCursorExpr(C)));
4239
4240 if (clang_isStatement(C.kind))
4241 return cxloc::translateSourceLocation(getCursorContext(C),
4242 getCursorStmt(C)->getLocStart());
4243
4244 if (C.kind == CXCursor_PreprocessingDirective) {
4245 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4246 return cxloc::translateSourceLocation(getCursorContext(C), L);
4247 }
4248
4249 if (C.kind == CXCursor_MacroExpansion) {
4250 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004251 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004252 return cxloc::translateSourceLocation(getCursorContext(C), L);
4253 }
4254
4255 if (C.kind == CXCursor_MacroDefinition) {
4256 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4257 return cxloc::translateSourceLocation(getCursorContext(C), L);
4258 }
4259
4260 if (C.kind == CXCursor_InclusionDirective) {
4261 SourceLocation L
4262 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4263 return cxloc::translateSourceLocation(getCursorContext(C), L);
4264 }
4265
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004266 if (clang_isAttribute(C.kind)) {
4267 SourceLocation L
4268 = cxcursor::getCursorAttr(C)->getLocation();
4269 return cxloc::translateSourceLocation(getCursorContext(C), L);
4270 }
4271
Guy Benyei11169dd2012-12-18 14:30:41 +00004272 if (!clang_isDeclaration(C.kind))
4273 return clang_getNullLocation();
4274
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004275 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004276 if (!D)
4277 return clang_getNullLocation();
4278
4279 SourceLocation Loc = D->getLocation();
4280 // FIXME: Multiple variables declared in a single declaration
4281 // currently lack the information needed to correctly determine their
4282 // ranges when accounting for the type-specifier. We use context
4283 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4284 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004285 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004286 if (!cxcursor::isFirstInDeclGroup(C))
4287 Loc = VD->getLocation();
4288 }
4289
4290 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004291 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004292 Loc = MD->getSelectorStartLoc();
4293
4294 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4295}
4296
4297} // end extern "C"
4298
4299CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4300 assert(TU);
4301
4302 // Guard against an invalid SourceLocation, or we may assert in one
4303 // of the following calls.
4304 if (SLoc.isInvalid())
4305 return clang_getNullCursor();
4306
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004307 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004308
4309 // Translate the given source location to make it point at the beginning of
4310 // the token under the cursor.
4311 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4312 CXXUnit->getASTContext().getLangOpts());
4313
4314 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4315 if (SLoc.isValid()) {
4316 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4317 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4318 /*VisitPreprocessorLast=*/true,
4319 /*VisitIncludedEntities=*/false,
4320 SourceLocation(SLoc));
4321 CursorVis.visitFileRegion();
4322 }
4323
4324 return Result;
4325}
4326
4327static SourceRange getRawCursorExtent(CXCursor C) {
4328 if (clang_isReference(C.kind)) {
4329 switch (C.kind) {
4330 case CXCursor_ObjCSuperClassRef:
4331 return getCursorObjCSuperClassRef(C).second;
4332
4333 case CXCursor_ObjCProtocolRef:
4334 return getCursorObjCProtocolRef(C).second;
4335
4336 case CXCursor_ObjCClassRef:
4337 return getCursorObjCClassRef(C).second;
4338
4339 case CXCursor_TypeRef:
4340 return getCursorTypeRef(C).second;
4341
4342 case CXCursor_TemplateRef:
4343 return getCursorTemplateRef(C).second;
4344
4345 case CXCursor_NamespaceRef:
4346 return getCursorNamespaceRef(C).second;
4347
4348 case CXCursor_MemberRef:
4349 return getCursorMemberRef(C).second;
4350
4351 case CXCursor_CXXBaseSpecifier:
4352 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4353
4354 case CXCursor_LabelRef:
4355 return getCursorLabelRef(C).second;
4356
4357 case CXCursor_OverloadedDeclRef:
4358 return getCursorOverloadedDeclRef(C).second;
4359
4360 case CXCursor_VariableRef:
4361 return getCursorVariableRef(C).second;
4362
4363 default:
4364 // FIXME: Need a way to enumerate all non-reference cases.
4365 llvm_unreachable("Missed a reference kind");
4366 }
4367 }
4368
4369 if (clang_isExpression(C.kind))
4370 return getCursorExpr(C)->getSourceRange();
4371
4372 if (clang_isStatement(C.kind))
4373 return getCursorStmt(C)->getSourceRange();
4374
4375 if (clang_isAttribute(C.kind))
4376 return getCursorAttr(C)->getRange();
4377
4378 if (C.kind == CXCursor_PreprocessingDirective)
4379 return cxcursor::getCursorPreprocessingDirective(C);
4380
4381 if (C.kind == CXCursor_MacroExpansion) {
4382 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004383 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004384 return TU->mapRangeFromPreamble(Range);
4385 }
4386
4387 if (C.kind == CXCursor_MacroDefinition) {
4388 ASTUnit *TU = getCursorASTUnit(C);
4389 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4390 return TU->mapRangeFromPreamble(Range);
4391 }
4392
4393 if (C.kind == CXCursor_InclusionDirective) {
4394 ASTUnit *TU = getCursorASTUnit(C);
4395 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4396 return TU->mapRangeFromPreamble(Range);
4397 }
4398
4399 if (C.kind == CXCursor_TranslationUnit) {
4400 ASTUnit *TU = getCursorASTUnit(C);
4401 FileID MainID = TU->getSourceManager().getMainFileID();
4402 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4403 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4404 return SourceRange(Start, End);
4405 }
4406
4407 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004408 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004409 if (!D)
4410 return SourceRange();
4411
4412 SourceRange R = D->getSourceRange();
4413 // FIXME: Multiple variables declared in a single declaration
4414 // currently lack the information needed to correctly determine their
4415 // ranges when accounting for the type-specifier. We use context
4416 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4417 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004418 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004419 if (!cxcursor::isFirstInDeclGroup(C))
4420 R.setBegin(VD->getLocation());
4421 }
4422 return R;
4423 }
4424 return SourceRange();
4425}
4426
4427/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4428/// the decl-specifier-seq for declarations.
4429static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4430 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004431 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004432 if (!D)
4433 return SourceRange();
4434
4435 SourceRange R = D->getSourceRange();
4436
4437 // Adjust the start of the location for declarations preceded by
4438 // declaration specifiers.
4439 SourceLocation StartLoc;
4440 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4441 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4442 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004443 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004444 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4445 StartLoc = TI->getTypeLoc().getLocStart();
4446 }
4447
4448 if (StartLoc.isValid() && R.getBegin().isValid() &&
4449 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4450 R.setBegin(StartLoc);
4451
4452 // FIXME: Multiple variables declared in a single declaration
4453 // currently lack the information needed to correctly determine their
4454 // ranges when accounting for the type-specifier. We use context
4455 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4456 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004457 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004458 if (!cxcursor::isFirstInDeclGroup(C))
4459 R.setBegin(VD->getLocation());
4460 }
4461
4462 return R;
4463 }
4464
4465 return getRawCursorExtent(C);
4466}
4467
4468extern "C" {
4469
4470CXSourceRange clang_getCursorExtent(CXCursor C) {
4471 SourceRange R = getRawCursorExtent(C);
4472 if (R.isInvalid())
4473 return clang_getNullRange();
4474
4475 return cxloc::translateSourceRange(getCursorContext(C), R);
4476}
4477
4478CXCursor clang_getCursorReferenced(CXCursor C) {
4479 if (clang_isInvalid(C.kind))
4480 return clang_getNullCursor();
4481
4482 CXTranslationUnit tu = getCursorTU(C);
4483 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004484 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004485 if (!D)
4486 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004487 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004488 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004489 if (const ObjCPropertyImplDecl *PropImpl =
4490 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004491 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4492 return MakeCXCursor(Property, tu);
4493
4494 return C;
4495 }
4496
4497 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004498 const Expr *E = getCursorExpr(C);
4499 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004500 if (D) {
4501 CXCursor declCursor = MakeCXCursor(D, tu);
4502 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4503 declCursor);
4504 return declCursor;
4505 }
4506
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004507 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004508 return MakeCursorOverloadedDeclRef(Ovl, tu);
4509
4510 return clang_getNullCursor();
4511 }
4512
4513 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004514 const Stmt *S = getCursorStmt(C);
4515 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004516 if (LabelDecl *label = Goto->getLabel())
4517 if (LabelStmt *labelS = label->getStmt())
4518 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4519
4520 return clang_getNullCursor();
4521 }
4522
4523 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004524 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004525 return MakeMacroDefinitionCursor(Def, tu);
4526 }
4527
4528 if (!clang_isReference(C.kind))
4529 return clang_getNullCursor();
4530
4531 switch (C.kind) {
4532 case CXCursor_ObjCSuperClassRef:
4533 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4534
4535 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004536 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4537 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004538 return MakeCXCursor(Def, tu);
4539
4540 return MakeCXCursor(Prot, tu);
4541 }
4542
4543 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004544 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4545 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004546 return MakeCXCursor(Def, tu);
4547
4548 return MakeCXCursor(Class, tu);
4549 }
4550
4551 case CXCursor_TypeRef:
4552 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4553
4554 case CXCursor_TemplateRef:
4555 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4556
4557 case CXCursor_NamespaceRef:
4558 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4559
4560 case CXCursor_MemberRef:
4561 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4562
4563 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004564 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004565 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4566 tu ));
4567 }
4568
4569 case CXCursor_LabelRef:
4570 // FIXME: We end up faking the "parent" declaration here because we
4571 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004572 return MakeCXCursor(getCursorLabelRef(C).first,
4573 cxtu::getASTUnit(tu)->getASTContext()
4574 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004575 tu);
4576
4577 case CXCursor_OverloadedDeclRef:
4578 return C;
4579
4580 case CXCursor_VariableRef:
4581 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4582
4583 default:
4584 // We would prefer to enumerate all non-reference cursor kinds here.
4585 llvm_unreachable("Unhandled reference cursor kind");
4586 }
4587}
4588
4589CXCursor clang_getCursorDefinition(CXCursor C) {
4590 if (clang_isInvalid(C.kind))
4591 return clang_getNullCursor();
4592
4593 CXTranslationUnit TU = getCursorTU(C);
4594
4595 bool WasReference = false;
4596 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4597 C = clang_getCursorReferenced(C);
4598 WasReference = true;
4599 }
4600
4601 if (C.kind == CXCursor_MacroExpansion)
4602 return clang_getCursorReferenced(C);
4603
4604 if (!clang_isDeclaration(C.kind))
4605 return clang_getNullCursor();
4606
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004607 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004608 if (!D)
4609 return clang_getNullCursor();
4610
4611 switch (D->getKind()) {
4612 // Declaration kinds that don't really separate the notions of
4613 // declaration and definition.
4614 case Decl::Namespace:
4615 case Decl::Typedef:
4616 case Decl::TypeAlias:
4617 case Decl::TypeAliasTemplate:
4618 case Decl::TemplateTypeParm:
4619 case Decl::EnumConstant:
4620 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004621 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004622 case Decl::IndirectField:
4623 case Decl::ObjCIvar:
4624 case Decl::ObjCAtDefsField:
4625 case Decl::ImplicitParam:
4626 case Decl::ParmVar:
4627 case Decl::NonTypeTemplateParm:
4628 case Decl::TemplateTemplateParm:
4629 case Decl::ObjCCategoryImpl:
4630 case Decl::ObjCImplementation:
4631 case Decl::AccessSpec:
4632 case Decl::LinkageSpec:
4633 case Decl::ObjCPropertyImpl:
4634 case Decl::FileScopeAsm:
4635 case Decl::StaticAssert:
4636 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004637 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004638 case Decl::Label: // FIXME: Is this right??
4639 case Decl::ClassScopeFunctionSpecialization:
4640 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004641 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004642 return C;
4643
4644 // Declaration kinds that don't make any sense here, but are
4645 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004646 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004647 case Decl::TranslationUnit:
4648 break;
4649
4650 // Declaration kinds for which the definition is not resolvable.
4651 case Decl::UnresolvedUsingTypename:
4652 case Decl::UnresolvedUsingValue:
4653 break;
4654
4655 case Decl::UsingDirective:
4656 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4657 TU);
4658
4659 case Decl::NamespaceAlias:
4660 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4661
4662 case Decl::Enum:
4663 case Decl::Record:
4664 case Decl::CXXRecord:
4665 case Decl::ClassTemplateSpecialization:
4666 case Decl::ClassTemplatePartialSpecialization:
4667 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4668 return MakeCXCursor(Def, TU);
4669 return clang_getNullCursor();
4670
4671 case Decl::Function:
4672 case Decl::CXXMethod:
4673 case Decl::CXXConstructor:
4674 case Decl::CXXDestructor:
4675 case Decl::CXXConversion: {
4676 const FunctionDecl *Def = 0;
4677 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004678 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004679 return clang_getNullCursor();
4680 }
4681
Larisse Voufo39a1e502013-08-06 01:03:05 +00004682 case Decl::Var:
4683 case Decl::VarTemplateSpecialization:
4684 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004685 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004686 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004687 return MakeCXCursor(Def, TU);
4688 return clang_getNullCursor();
4689 }
4690
4691 case Decl::FunctionTemplate: {
4692 const FunctionDecl *Def = 0;
4693 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4694 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4695 return clang_getNullCursor();
4696 }
4697
4698 case Decl::ClassTemplate: {
4699 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4700 ->getDefinition())
4701 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4702 TU);
4703 return clang_getNullCursor();
4704 }
4705
Larisse Voufo39a1e502013-08-06 01:03:05 +00004706 case Decl::VarTemplate: {
4707 if (VarDecl *Def =
4708 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4709 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4710 return clang_getNullCursor();
4711 }
4712
Guy Benyei11169dd2012-12-18 14:30:41 +00004713 case Decl::Using:
4714 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4715 D->getLocation(), TU);
4716
4717 case Decl::UsingShadow:
4718 return clang_getCursorDefinition(
4719 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4720 TU));
4721
4722 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004723 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004724 if (Method->isThisDeclarationADefinition())
4725 return C;
4726
4727 // Dig out the method definition in the associated
4728 // @implementation, if we have it.
4729 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004730 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004731 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4732 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4733 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4734 Method->isInstanceMethod()))
4735 if (Def->isThisDeclarationADefinition())
4736 return MakeCXCursor(Def, TU);
4737
4738 return clang_getNullCursor();
4739 }
4740
4741 case Decl::ObjCCategory:
4742 if (ObjCCategoryImplDecl *Impl
4743 = cast<ObjCCategoryDecl>(D)->getImplementation())
4744 return MakeCXCursor(Impl, TU);
4745 return clang_getNullCursor();
4746
4747 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004748 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004749 return MakeCXCursor(Def, TU);
4750 return clang_getNullCursor();
4751
4752 case Decl::ObjCInterface: {
4753 // There are two notions of a "definition" for an Objective-C
4754 // class: the interface and its implementation. When we resolved a
4755 // reference to an Objective-C class, produce the @interface as
4756 // the definition; when we were provided with the interface,
4757 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004758 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004759 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004760 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004761 return MakeCXCursor(Def, TU);
4762 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4763 return MakeCXCursor(Impl, TU);
4764 return clang_getNullCursor();
4765 }
4766
4767 case Decl::ObjCProperty:
4768 // FIXME: We don't really know where to find the
4769 // ObjCPropertyImplDecls that implement this property.
4770 return clang_getNullCursor();
4771
4772 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004773 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004774 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004775 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004776 return MakeCXCursor(Def, TU);
4777
4778 return clang_getNullCursor();
4779
4780 case Decl::Friend:
4781 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4782 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4783 return clang_getNullCursor();
4784
4785 case Decl::FriendTemplate:
4786 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4787 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4788 return clang_getNullCursor();
4789 }
4790
4791 return clang_getNullCursor();
4792}
4793
4794unsigned clang_isCursorDefinition(CXCursor C) {
4795 if (!clang_isDeclaration(C.kind))
4796 return 0;
4797
4798 return clang_getCursorDefinition(C) == C;
4799}
4800
4801CXCursor clang_getCanonicalCursor(CXCursor C) {
4802 if (!clang_isDeclaration(C.kind))
4803 return C;
4804
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004805 if (const Decl *D = getCursorDecl(C)) {
4806 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004807 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4808 return MakeCXCursor(CatD, getCursorTU(C));
4809
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004810 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4811 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004812 return MakeCXCursor(IFD, getCursorTU(C));
4813
4814 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4815 }
4816
4817 return C;
4818}
4819
4820int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4821 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4822}
4823
4824unsigned clang_getNumOverloadedDecls(CXCursor C) {
4825 if (C.kind != CXCursor_OverloadedDeclRef)
4826 return 0;
4827
4828 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004829 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004830 return E->getNumDecls();
4831
4832 if (OverloadedTemplateStorage *S
4833 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4834 return S->size();
4835
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004836 const Decl *D = Storage.get<const Decl *>();
4837 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004838 return Using->shadow_size();
4839
4840 return 0;
4841}
4842
4843CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4844 if (cursor.kind != CXCursor_OverloadedDeclRef)
4845 return clang_getNullCursor();
4846
4847 if (index >= clang_getNumOverloadedDecls(cursor))
4848 return clang_getNullCursor();
4849
4850 CXTranslationUnit TU = getCursorTU(cursor);
4851 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004852 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004853 return MakeCXCursor(E->decls_begin()[index], TU);
4854
4855 if (OverloadedTemplateStorage *S
4856 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4857 return MakeCXCursor(S->begin()[index], TU);
4858
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004859 const Decl *D = Storage.get<const Decl *>();
4860 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004861 // FIXME: This is, unfortunately, linear time.
4862 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4863 std::advance(Pos, index);
4864 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4865 }
4866
4867 return clang_getNullCursor();
4868}
4869
4870void clang_getDefinitionSpellingAndExtent(CXCursor C,
4871 const char **startBuf,
4872 const char **endBuf,
4873 unsigned *startLine,
4874 unsigned *startColumn,
4875 unsigned *endLine,
4876 unsigned *endColumn) {
4877 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004878 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004879 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4880
4881 SourceManager &SM = FD->getASTContext().getSourceManager();
4882 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4883 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4884 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4885 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4886 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4887 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4888}
4889
4890
4891CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4892 unsigned PieceIndex) {
4893 RefNamePieces Pieces;
4894
4895 switch (C.kind) {
4896 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004897 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004898 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4899 E->getQualifierLoc().getSourceRange());
4900 break;
4901
4902 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004903 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004904 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4905 E->getQualifierLoc().getSourceRange(),
4906 E->getOptionalExplicitTemplateArgs());
4907 break;
4908
4909 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004910 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004911 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004912 const Expr *Callee = OCE->getCallee();
4913 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004914 Callee = ICE->getSubExpr();
4915
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004916 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004917 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4918 DRE->getQualifierLoc().getSourceRange());
4919 }
4920 break;
4921
4922 default:
4923 break;
4924 }
4925
4926 if (Pieces.empty()) {
4927 if (PieceIndex == 0)
4928 return clang_getCursorExtent(C);
4929 } else if (PieceIndex < Pieces.size()) {
4930 SourceRange R = Pieces[PieceIndex];
4931 if (R.isValid())
4932 return cxloc::translateSourceRange(getCursorContext(C), R);
4933 }
4934
4935 return clang_getNullRange();
4936}
4937
4938void clang_enableStackTraces(void) {
4939 llvm::sys::PrintStackTraceOnErrorSignal();
4940}
4941
4942void clang_executeOnThread(void (*fn)(void*), void *user_data,
4943 unsigned stack_size) {
4944 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4945}
4946
4947} // end: extern "C"
4948
4949//===----------------------------------------------------------------------===//
4950// Token-based Operations.
4951//===----------------------------------------------------------------------===//
4952
4953/* CXToken layout:
4954 * int_data[0]: a CXTokenKind
4955 * int_data[1]: starting token location
4956 * int_data[2]: token length
4957 * int_data[3]: reserved
4958 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4959 * otherwise unused.
4960 */
4961extern "C" {
4962
4963CXTokenKind clang_getTokenKind(CXToken CXTok) {
4964 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4965}
4966
4967CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4968 switch (clang_getTokenKind(CXTok)) {
4969 case CXToken_Identifier:
4970 case CXToken_Keyword:
4971 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004972 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004973 ->getNameStart());
4974
4975 case CXToken_Literal: {
4976 // We have stashed the starting pointer in the ptr_data field. Use it.
4977 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004978 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004979 }
4980
4981 case CXToken_Punctuation:
4982 case CXToken_Comment:
4983 break;
4984 }
4985
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004986 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004987 LOG_BAD_TU(TU);
4988 return cxstring::createEmpty();
4989 }
4990
Guy Benyei11169dd2012-12-18 14:30:41 +00004991 // We have to find the starting buffer pointer the hard way, by
4992 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004993 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004994 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00004995 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00004996
4997 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
4998 std::pair<FileID, unsigned> LocInfo
4999 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5000 bool Invalid = false;
5001 StringRef Buffer
5002 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5003 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005004 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005005
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005006 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005007}
5008
5009CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005010 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005011 LOG_BAD_TU(TU);
5012 return clang_getNullLocation();
5013 }
5014
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005015 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005016 if (!CXXUnit)
5017 return clang_getNullLocation();
5018
5019 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5020 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5021}
5022
5023CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005024 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005025 LOG_BAD_TU(TU);
5026 return clang_getNullRange();
5027 }
5028
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005029 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005030 if (!CXXUnit)
5031 return clang_getNullRange();
5032
5033 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5034 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5035}
5036
5037static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5038 SmallVectorImpl<CXToken> &CXTokens) {
5039 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5040 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005041 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005042 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005043 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005044
5045 // Cannot tokenize across files.
5046 if (BeginLocInfo.first != EndLocInfo.first)
5047 return;
5048
5049 // Create a lexer
5050 bool Invalid = false;
5051 StringRef Buffer
5052 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5053 if (Invalid)
5054 return;
5055
5056 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5057 CXXUnit->getASTContext().getLangOpts(),
5058 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5059 Lex.SetCommentRetentionState(true);
5060
5061 // Lex tokens until we hit the end of the range.
5062 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5063 Token Tok;
5064 bool previousWasAt = false;
5065 do {
5066 // Lex the next token
5067 Lex.LexFromRawLexer(Tok);
5068 if (Tok.is(tok::eof))
5069 break;
5070
5071 // Initialize the CXToken.
5072 CXToken CXTok;
5073
5074 // - Common fields
5075 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5076 CXTok.int_data[2] = Tok.getLength();
5077 CXTok.int_data[3] = 0;
5078
5079 // - Kind-specific fields
5080 if (Tok.isLiteral()) {
5081 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005082 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005083 } else if (Tok.is(tok::raw_identifier)) {
5084 // Lookup the identifier to determine whether we have a keyword.
5085 IdentifierInfo *II
5086 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5087
5088 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5089 CXTok.int_data[0] = CXToken_Keyword;
5090 }
5091 else {
5092 CXTok.int_data[0] = Tok.is(tok::identifier)
5093 ? CXToken_Identifier
5094 : CXToken_Keyword;
5095 }
5096 CXTok.ptr_data = II;
5097 } else if (Tok.is(tok::comment)) {
5098 CXTok.int_data[0] = CXToken_Comment;
5099 CXTok.ptr_data = 0;
5100 } else {
5101 CXTok.int_data[0] = CXToken_Punctuation;
5102 CXTok.ptr_data = 0;
5103 }
5104 CXTokens.push_back(CXTok);
5105 previousWasAt = Tok.is(tok::at);
5106 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5107}
5108
5109void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5110 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005111 LOG_FUNC_SECTION {
5112 *Log << TU << ' ' << Range;
5113 }
5114
Guy Benyei11169dd2012-12-18 14:30:41 +00005115 if (Tokens)
5116 *Tokens = 0;
5117 if (NumTokens)
5118 *NumTokens = 0;
5119
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005120 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005121 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005122 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005123 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005124
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005125 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005126 if (!CXXUnit || !Tokens || !NumTokens)
5127 return;
5128
5129 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5130
5131 SourceRange R = cxloc::translateCXSourceRange(Range);
5132 if (R.isInvalid())
5133 return;
5134
5135 SmallVector<CXToken, 32> CXTokens;
5136 getTokens(CXXUnit, R, CXTokens);
5137
5138 if (CXTokens.empty())
5139 return;
5140
5141 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5142 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5143 *NumTokens = CXTokens.size();
5144}
5145
5146void clang_disposeTokens(CXTranslationUnit TU,
5147 CXToken *Tokens, unsigned NumTokens) {
5148 free(Tokens);
5149}
5150
5151} // end: extern "C"
5152
5153//===----------------------------------------------------------------------===//
5154// Token annotation APIs.
5155//===----------------------------------------------------------------------===//
5156
Guy Benyei11169dd2012-12-18 14:30:41 +00005157static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5158 CXCursor parent,
5159 CXClientData client_data);
5160static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5161 CXClientData client_data);
5162
5163namespace {
5164class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005165 CXToken *Tokens;
5166 CXCursor *Cursors;
5167 unsigned NumTokens;
5168 unsigned TokIdx;
5169 unsigned PreprocessingTokIdx;
5170 CursorVisitor AnnotateVis;
5171 SourceManager &SrcMgr;
5172 bool HasContextSensitiveKeywords;
5173
5174 struct PostChildrenInfo {
5175 CXCursor Cursor;
5176 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005177 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005178 unsigned BeforeChildrenTokenIdx;
5179 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005180 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005181
5182 CXToken &getTok(unsigned Idx) {
5183 assert(Idx < NumTokens);
5184 return Tokens[Idx];
5185 }
5186 const CXToken &getTok(unsigned Idx) const {
5187 assert(Idx < NumTokens);
5188 return Tokens[Idx];
5189 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005190 bool MoreTokens() const { return TokIdx < NumTokens; }
5191 unsigned NextToken() const { return TokIdx; }
5192 void AdvanceToken() { ++TokIdx; }
5193 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005194 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005195 }
5196 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005197 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005198 }
5199 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005200 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005201 }
5202
5203 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005204 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005205 SourceRange);
5206
5207public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005208 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005209 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005210 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005211 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005212 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005213 AnnotateTokensVisitor, this,
5214 /*VisitPreprocessorLast=*/true,
5215 /*VisitIncludedEntities=*/false,
5216 RegionOfInterest,
5217 /*VisitDeclsOnly=*/false,
5218 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005219 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005220 HasContextSensitiveKeywords(false) { }
5221
5222 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5223 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5224 bool postVisitChildren(CXCursor cursor);
5225 void AnnotateTokens();
5226
5227 /// \brief Determine whether the annotator saw any cursors that have
5228 /// context-sensitive keywords.
5229 bool hasContextSensitiveKeywords() const {
5230 return HasContextSensitiveKeywords;
5231 }
5232
5233 ~AnnotateTokensWorker() {
5234 assert(PostChildrenInfos.empty());
5235 }
5236};
5237}
5238
5239void AnnotateTokensWorker::AnnotateTokens() {
5240 // Walk the AST within the region of interest, annotating tokens
5241 // along the way.
5242 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005243}
Guy Benyei11169dd2012-12-18 14:30:41 +00005244
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005245static inline void updateCursorAnnotation(CXCursor &Cursor,
5246 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005247 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005248 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005249 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005250}
5251
5252/// \brief It annotates and advances tokens with a cursor until the comparison
5253//// between the cursor location and the source range is the same as
5254/// \arg compResult.
5255///
5256/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5257/// Pass RangeOverlap to annotate tokens inside a range.
5258void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5259 RangeComparisonResult compResult,
5260 SourceRange range) {
5261 while (MoreTokens()) {
5262 const unsigned I = NextToken();
5263 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005264 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5265 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005266
5267 SourceLocation TokLoc = GetTokenLoc(I);
5268 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005269 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005270 AdvanceToken();
5271 continue;
5272 }
5273 break;
5274 }
5275}
5276
5277/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005278/// \returns true if it advanced beyond all macro tokens, false otherwise.
5279bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005280 CXCursor updateC,
5281 RangeComparisonResult compResult,
5282 SourceRange range) {
5283 assert(MoreTokens());
5284 assert(isFunctionMacroToken(NextToken()) &&
5285 "Should be called only for macro arg tokens");
5286
5287 // This works differently than annotateAndAdvanceTokens; because expanded
5288 // macro arguments can have arbitrary translation-unit source order, we do not
5289 // advance the token index one by one until a token fails the range test.
5290 // We only advance once past all of the macro arg tokens if all of them
5291 // pass the range test. If one of them fails we keep the token index pointing
5292 // at the start of the macro arg tokens so that the failing token will be
5293 // annotated by a subsequent annotation try.
5294
5295 bool atLeastOneCompFail = false;
5296
5297 unsigned I = NextToken();
5298 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5299 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5300 if (TokLoc.isFileID())
5301 continue; // not macro arg token, it's parens or comma.
5302 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5303 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5304 Cursors[I] = updateC;
5305 } else
5306 atLeastOneCompFail = true;
5307 }
5308
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005309 if (atLeastOneCompFail)
5310 return false;
5311
5312 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5313 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005314}
5315
5316enum CXChildVisitResult
5317AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005318 SourceRange cursorRange = getRawCursorExtent(cursor);
5319 if (cursorRange.isInvalid())
5320 return CXChildVisit_Recurse;
5321
5322 if (!HasContextSensitiveKeywords) {
5323 // Objective-C properties can have context-sensitive keywords.
5324 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005325 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005326 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5327 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5328 }
5329 // Objective-C methods can have context-sensitive keywords.
5330 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5331 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005332 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005333 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5334 if (Method->getObjCDeclQualifier())
5335 HasContextSensitiveKeywords = true;
5336 else {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005337 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5338 PEnd = Method->param_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00005339 P != PEnd; ++P) {
5340 if ((*P)->getObjCDeclQualifier()) {
5341 HasContextSensitiveKeywords = true;
5342 break;
5343 }
5344 }
5345 }
5346 }
5347 }
5348 // C++ methods can have context-sensitive keywords.
5349 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005350 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005351 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5352 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5353 HasContextSensitiveKeywords = true;
5354 }
5355 }
5356 // C++ classes can have context-sensitive keywords.
5357 else if (cursor.kind == CXCursor_StructDecl ||
5358 cursor.kind == CXCursor_ClassDecl ||
5359 cursor.kind == CXCursor_ClassTemplate ||
5360 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005361 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005362 if (D->hasAttr<FinalAttr>())
5363 HasContextSensitiveKeywords = true;
5364 }
5365 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005366
5367 // Don't override a property annotation with its getter/setter method.
5368 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5369 parent.kind == CXCursor_ObjCPropertyDecl)
5370 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005371
5372 if (clang_isPreprocessing(cursor.kind)) {
5373 // Items in the preprocessing record are kept separate from items in
5374 // declarations, so we keep a separate token index.
5375 unsigned SavedTokIdx = TokIdx;
5376 TokIdx = PreprocessingTokIdx;
5377
5378 // Skip tokens up until we catch up to the beginning of the preprocessing
5379 // entry.
5380 while (MoreTokens()) {
5381 const unsigned I = NextToken();
5382 SourceLocation TokLoc = GetTokenLoc(I);
5383 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5384 case RangeBefore:
5385 AdvanceToken();
5386 continue;
5387 case RangeAfter:
5388 case RangeOverlap:
5389 break;
5390 }
5391 break;
5392 }
5393
5394 // Look at all of the tokens within this range.
5395 while (MoreTokens()) {
5396 const unsigned I = NextToken();
5397 SourceLocation TokLoc = GetTokenLoc(I);
5398 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5399 case RangeBefore:
5400 llvm_unreachable("Infeasible");
5401 case RangeAfter:
5402 break;
5403 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005404 // For macro expansions, just note where the beginning of the macro
5405 // expansion occurs.
5406 if (cursor.kind == CXCursor_MacroExpansion) {
5407 if (TokLoc == cursorRange.getBegin())
5408 Cursors[I] = cursor;
5409 AdvanceToken();
5410 break;
5411 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005412 // We may have already annotated macro names inside macro definitions.
5413 if (Cursors[I].kind != CXCursor_MacroExpansion)
5414 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005415 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005416 continue;
5417 }
5418 break;
5419 }
5420
5421 // Save the preprocessing token index; restore the non-preprocessing
5422 // token index.
5423 PreprocessingTokIdx = TokIdx;
5424 TokIdx = SavedTokIdx;
5425 return CXChildVisit_Recurse;
5426 }
5427
5428 if (cursorRange.isInvalid())
5429 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005430
5431 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005432 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005433 const enum CXCursorKind K = clang_getCursorKind(parent);
5434 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005435 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5436 // Attributes are annotated out-of-order, skip tokens until we reach it.
5437 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005438 ? clang_getNullCursor() : parent;
5439
5440 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5441
5442 // Avoid having the cursor of an expression "overwrite" the annotation of the
5443 // variable declaration that it belongs to.
5444 // This can happen for C++ constructor expressions whose range generally
5445 // include the variable declaration, e.g.:
5446 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005447 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005448 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005449 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005450 const unsigned I = NextToken();
5451 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5452 E->getLocStart() == D->getLocation() &&
5453 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005454 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005455 AdvanceToken();
5456 }
5457 }
5458 }
5459
5460 // Before recursing into the children keep some state that we are going
5461 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5462 // extra work after the child nodes are visited.
5463 // Note that we don't call VisitChildren here to avoid traversing statements
5464 // code-recursively which can blow the stack.
5465
5466 PostChildrenInfo Info;
5467 Info.Cursor = cursor;
5468 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005469 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005470 Info.BeforeChildrenTokenIdx = NextToken();
5471 PostChildrenInfos.push_back(Info);
5472
5473 return CXChildVisit_Recurse;
5474}
5475
5476bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5477 if (PostChildrenInfos.empty())
5478 return false;
5479 const PostChildrenInfo &Info = PostChildrenInfos.back();
5480 if (!clang_equalCursors(Info.Cursor, cursor))
5481 return false;
5482
5483 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5484 const unsigned AfterChildren = NextToken();
5485 SourceRange cursorRange = Info.CursorRange;
5486
5487 // Scan the tokens that are at the end of the cursor, but are not captured
5488 // but the child cursors.
5489 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5490
5491 // Scan the tokens that are at the beginning of the cursor, but are not
5492 // capture by the child cursors.
5493 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5494 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5495 break;
5496
5497 Cursors[I] = cursor;
5498 }
5499
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005500 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5501 // encountered the attribute cursor.
5502 if (clang_isAttribute(cursor.kind))
5503 TokIdx = Info.BeforeReachingCursorIdx;
5504
Guy Benyei11169dd2012-12-18 14:30:41 +00005505 PostChildrenInfos.pop_back();
5506 return false;
5507}
5508
5509static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5510 CXCursor parent,
5511 CXClientData client_data) {
5512 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5513}
5514
5515static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5516 CXClientData client_data) {
5517 return static_cast<AnnotateTokensWorker*>(client_data)->
5518 postVisitChildren(cursor);
5519}
5520
5521namespace {
5522
5523/// \brief Uses the macro expansions in the preprocessing record to find
5524/// and mark tokens that are macro arguments. This info is used by the
5525/// AnnotateTokensWorker.
5526class MarkMacroArgTokensVisitor {
5527 SourceManager &SM;
5528 CXToken *Tokens;
5529 unsigned NumTokens;
5530 unsigned CurIdx;
5531
5532public:
5533 MarkMacroArgTokensVisitor(SourceManager &SM,
5534 CXToken *tokens, unsigned numTokens)
5535 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5536
5537 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5538 if (cursor.kind != CXCursor_MacroExpansion)
5539 return CXChildVisit_Continue;
5540
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005541 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005542 if (macroRange.getBegin() == macroRange.getEnd())
5543 return CXChildVisit_Continue; // it's not a function macro.
5544
5545 for (; CurIdx < NumTokens; ++CurIdx) {
5546 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5547 macroRange.getBegin()))
5548 break;
5549 }
5550
5551 if (CurIdx == NumTokens)
5552 return CXChildVisit_Break;
5553
5554 for (; CurIdx < NumTokens; ++CurIdx) {
5555 SourceLocation tokLoc = getTokenLoc(CurIdx);
5556 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5557 break;
5558
5559 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5560 }
5561
5562 if (CurIdx == NumTokens)
5563 return CXChildVisit_Break;
5564
5565 return CXChildVisit_Continue;
5566 }
5567
5568private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005569 CXToken &getTok(unsigned Idx) {
5570 assert(Idx < NumTokens);
5571 return Tokens[Idx];
5572 }
5573 const CXToken &getTok(unsigned Idx) const {
5574 assert(Idx < NumTokens);
5575 return Tokens[Idx];
5576 }
5577
Guy Benyei11169dd2012-12-18 14:30:41 +00005578 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005579 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005580 }
5581
5582 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5583 // The third field is reserved and currently not used. Use it here
5584 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005585 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005586 }
5587};
5588
5589} // end anonymous namespace
5590
5591static CXChildVisitResult
5592MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5593 CXClientData client_data) {
5594 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5595 parent);
5596}
5597
5598namespace {
5599 struct clang_annotateTokens_Data {
5600 CXTranslationUnit TU;
5601 ASTUnit *CXXUnit;
5602 CXToken *Tokens;
5603 unsigned NumTokens;
5604 CXCursor *Cursors;
5605 };
5606}
5607
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005608/// \brief Used by \c annotatePreprocessorTokens.
5609/// \returns true if lexing was finished, false otherwise.
5610static bool lexNext(Lexer &Lex, Token &Tok,
5611 unsigned &NextIdx, unsigned NumTokens) {
5612 if (NextIdx >= NumTokens)
5613 return true;
5614
5615 ++NextIdx;
5616 Lex.LexFromRawLexer(Tok);
5617 if (Tok.is(tok::eof))
5618 return true;
5619
5620 return false;
5621}
5622
Guy Benyei11169dd2012-12-18 14:30:41 +00005623static void annotatePreprocessorTokens(CXTranslationUnit TU,
5624 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005625 CXCursor *Cursors,
5626 CXToken *Tokens,
5627 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005628 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005629
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005630 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005631 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5632 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005633 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005634 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005635 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005636
5637 if (BeginLocInfo.first != EndLocInfo.first)
5638 return;
5639
5640 StringRef Buffer;
5641 bool Invalid = false;
5642 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5643 if (Buffer.empty() || Invalid)
5644 return;
5645
5646 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5647 CXXUnit->getASTContext().getLangOpts(),
5648 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5649 Buffer.end());
5650 Lex.SetCommentRetentionState(true);
5651
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005652 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005653 // Lex tokens in raw mode until we hit the end of the range, to avoid
5654 // entering #includes or expanding macros.
5655 while (true) {
5656 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005657 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5658 break;
5659 unsigned TokIdx = NextIdx-1;
5660 assert(Tok.getLocation() ==
5661 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005662
5663 reprocess:
5664 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005665 // We have found a preprocessing directive. Annotate the tokens
5666 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005667 //
5668 // FIXME: Some simple tests here could identify macro definitions and
5669 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005670
5671 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005672 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5673 break;
5674
5675 MacroInfo *MI = 0;
5676 if (Tok.is(tok::raw_identifier) &&
5677 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5678 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5679 break;
5680
5681 if (Tok.is(tok::raw_identifier)) {
5682 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5683 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5684 SourceLocation MappedTokLoc =
5685 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5686 MI = getMacroInfo(II, MappedTokLoc, TU);
5687 }
5688 }
5689
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005690 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005691 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005692 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5693 finished = true;
5694 break;
5695 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005696 // If we are in a macro definition, check if the token was ever a
5697 // macro name and annotate it if that's the case.
5698 if (MI) {
5699 SourceLocation SaveLoc = Tok.getLocation();
5700 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5701 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5702 Tok.setLocation(SaveLoc);
5703 if (MacroDef)
5704 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5705 Tok.getLocation(), TU);
5706 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005707 } while (!Tok.isAtStartOfLine());
5708
5709 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5710 assert(TokIdx <= LastIdx);
5711 SourceLocation EndLoc =
5712 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5713 CXCursor Cursor =
5714 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5715
5716 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005717 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005718
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005719 if (finished)
5720 break;
5721 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005722 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005723 }
5724}
5725
5726// This gets run a separate thread to avoid stack blowout.
5727static void clang_annotateTokensImpl(void *UserData) {
5728 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5729 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5730 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5731 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5732 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5733
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005734 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005735 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5736 setThreadBackgroundPriority();
5737
5738 // Determine the region of interest, which contains all of the tokens.
5739 SourceRange RegionOfInterest;
5740 RegionOfInterest.setBegin(
5741 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5742 RegionOfInterest.setEnd(
5743 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5744 Tokens[NumTokens-1])));
5745
Guy Benyei11169dd2012-12-18 14:30:41 +00005746 // Relex the tokens within the source range to look for preprocessing
5747 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005748 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005749
5750 // If begin location points inside a macro argument, set it to the expansion
5751 // location so we can have the full context when annotating semantically.
5752 {
5753 SourceManager &SM = CXXUnit->getSourceManager();
5754 SourceLocation Loc =
5755 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5756 if (Loc.isMacroID())
5757 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5758 }
5759
Guy Benyei11169dd2012-12-18 14:30:41 +00005760 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5761 // Search and mark tokens that are macro argument expansions.
5762 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5763 Tokens, NumTokens);
5764 CursorVisitor MacroArgMarker(TU,
5765 MarkMacroArgTokensVisitorDelegate, &Visitor,
5766 /*VisitPreprocessorLast=*/true,
5767 /*VisitIncludedEntities=*/false,
5768 RegionOfInterest);
5769 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5770 }
5771
5772 // Annotate all of the source locations in the region of interest that map to
5773 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005774 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005775
5776 // FIXME: We use a ridiculous stack size here because the data-recursion
5777 // algorithm uses a large stack frame than the non-data recursive version,
5778 // and AnnotationTokensWorker currently transforms the data-recursion
5779 // algorithm back into a traditional recursion by explicitly calling
5780 // VisitChildren(). We will need to remove this explicit recursive call.
5781 W.AnnotateTokens();
5782
5783 // If we ran into any entities that involve context-sensitive keywords,
5784 // take another pass through the tokens to mark them as such.
5785 if (W.hasContextSensitiveKeywords()) {
5786 for (unsigned I = 0; I != NumTokens; ++I) {
5787 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5788 continue;
5789
5790 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5791 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005792 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005793 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5794 if (Property->getPropertyAttributesAsWritten() != 0 &&
5795 llvm::StringSwitch<bool>(II->getName())
5796 .Case("readonly", true)
5797 .Case("assign", true)
5798 .Case("unsafe_unretained", true)
5799 .Case("readwrite", true)
5800 .Case("retain", true)
5801 .Case("copy", true)
5802 .Case("nonatomic", true)
5803 .Case("atomic", true)
5804 .Case("getter", true)
5805 .Case("setter", true)
5806 .Case("strong", true)
5807 .Case("weak", true)
5808 .Default(false))
5809 Tokens[I].int_data[0] = CXToken_Keyword;
5810 }
5811 continue;
5812 }
5813
5814 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5815 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5816 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5817 if (llvm::StringSwitch<bool>(II->getName())
5818 .Case("in", true)
5819 .Case("out", true)
5820 .Case("inout", true)
5821 .Case("oneway", true)
5822 .Case("bycopy", true)
5823 .Case("byref", true)
5824 .Default(false))
5825 Tokens[I].int_data[0] = CXToken_Keyword;
5826 continue;
5827 }
5828
5829 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5830 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5831 Tokens[I].int_data[0] = CXToken_Keyword;
5832 continue;
5833 }
5834 }
5835 }
5836}
5837
5838extern "C" {
5839
5840void clang_annotateTokens(CXTranslationUnit TU,
5841 CXToken *Tokens, unsigned NumTokens,
5842 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005843 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005844 LOG_BAD_TU(TU);
5845 return;
5846 }
5847 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005848 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005849 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005850 }
5851
5852 LOG_FUNC_SECTION {
5853 *Log << TU << ' ';
5854 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5855 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5856 *Log << clang_getRange(bloc, eloc);
5857 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005858
5859 // Any token we don't specifically annotate will have a NULL cursor.
5860 CXCursor C = clang_getNullCursor();
5861 for (unsigned I = 0; I != NumTokens; ++I)
5862 Cursors[I] = C;
5863
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005864 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005865 if (!CXXUnit)
5866 return;
5867
5868 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5869
5870 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5871 llvm::CrashRecoveryContext CRC;
5872 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5873 GetSafetyThreadStackSize() * 2)) {
5874 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5875 }
5876}
5877
5878} // end: extern "C"
5879
5880//===----------------------------------------------------------------------===//
5881// Operations for querying linkage of a cursor.
5882//===----------------------------------------------------------------------===//
5883
5884extern "C" {
5885CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5886 if (!clang_isDeclaration(cursor.kind))
5887 return CXLinkage_Invalid;
5888
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005889 const Decl *D = cxcursor::getCursorDecl(cursor);
5890 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005891 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005892 case NoLinkage:
5893 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005894 case InternalLinkage: return CXLinkage_Internal;
5895 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5896 case ExternalLinkage: return CXLinkage_External;
5897 };
5898
5899 return CXLinkage_Invalid;
5900}
5901} // end: extern "C"
5902
5903//===----------------------------------------------------------------------===//
5904// Operations for querying language of a cursor.
5905//===----------------------------------------------------------------------===//
5906
5907static CXLanguageKind getDeclLanguage(const Decl *D) {
5908 if (!D)
5909 return CXLanguage_C;
5910
5911 switch (D->getKind()) {
5912 default:
5913 break;
5914 case Decl::ImplicitParam:
5915 case Decl::ObjCAtDefsField:
5916 case Decl::ObjCCategory:
5917 case Decl::ObjCCategoryImpl:
5918 case Decl::ObjCCompatibleAlias:
5919 case Decl::ObjCImplementation:
5920 case Decl::ObjCInterface:
5921 case Decl::ObjCIvar:
5922 case Decl::ObjCMethod:
5923 case Decl::ObjCProperty:
5924 case Decl::ObjCPropertyImpl:
5925 case Decl::ObjCProtocol:
5926 return CXLanguage_ObjC;
5927 case Decl::CXXConstructor:
5928 case Decl::CXXConversion:
5929 case Decl::CXXDestructor:
5930 case Decl::CXXMethod:
5931 case Decl::CXXRecord:
5932 case Decl::ClassTemplate:
5933 case Decl::ClassTemplatePartialSpecialization:
5934 case Decl::ClassTemplateSpecialization:
5935 case Decl::Friend:
5936 case Decl::FriendTemplate:
5937 case Decl::FunctionTemplate:
5938 case Decl::LinkageSpec:
5939 case Decl::Namespace:
5940 case Decl::NamespaceAlias:
5941 case Decl::NonTypeTemplateParm:
5942 case Decl::StaticAssert:
5943 case Decl::TemplateTemplateParm:
5944 case Decl::TemplateTypeParm:
5945 case Decl::UnresolvedUsingTypename:
5946 case Decl::UnresolvedUsingValue:
5947 case Decl::Using:
5948 case Decl::UsingDirective:
5949 case Decl::UsingShadow:
5950 return CXLanguage_CPlusPlus;
5951 }
5952
5953 return CXLanguage_C;
5954}
5955
5956extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005957
5958static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5959 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5960 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005961
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005962 switch (D->getAvailability()) {
5963 case AR_Available:
5964 case AR_NotYetIntroduced:
5965 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005966 return getCursorAvailabilityForDecl(
5967 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005968 return CXAvailability_Available;
5969
5970 case AR_Deprecated:
5971 return CXAvailability_Deprecated;
5972
5973 case AR_Unavailable:
5974 return CXAvailability_NotAvailable;
5975 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005976
5977 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005978}
5979
Guy Benyei11169dd2012-12-18 14:30:41 +00005980enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5981 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005982 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5983 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005984
5985 return CXAvailability_Available;
5986}
5987
5988static CXVersion convertVersion(VersionTuple In) {
5989 CXVersion Out = { -1, -1, -1 };
5990 if (In.empty())
5991 return Out;
5992
5993 Out.Major = In.getMajor();
5994
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005995 Optional<unsigned> Minor = In.getMinor();
5996 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00005997 Out.Minor = *Minor;
5998 else
5999 return Out;
6000
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006001 Optional<unsigned> Subminor = In.getSubminor();
6002 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006003 Out.Subminor = *Subminor;
6004
6005 return Out;
6006}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006007
6008static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6009 int *always_deprecated,
6010 CXString *deprecated_message,
6011 int *always_unavailable,
6012 CXString *unavailable_message,
6013 CXPlatformAvailability *availability,
6014 int availability_size) {
6015 bool HadAvailAttr = false;
6016 int N = 0;
6017 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
6018 ++A) {
6019 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
6020 HadAvailAttr = true;
6021 if (always_deprecated)
6022 *always_deprecated = 1;
6023 if (deprecated_message)
6024 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
6025 continue;
6026 }
6027
6028 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
6029 HadAvailAttr = true;
6030 if (always_unavailable)
6031 *always_unavailable = 1;
6032 if (unavailable_message) {
6033 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6034 }
6035 continue;
6036 }
6037
6038 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
6039 HadAvailAttr = true;
6040 if (N < availability_size) {
6041 availability[N].Platform
6042 = cxstring::createDup(Avail->getPlatform()->getName());
6043 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6044 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6045 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6046 availability[N].Unavailable = Avail->getUnavailable();
6047 availability[N].Message = cxstring::createDup(Avail->getMessage());
6048 }
6049 ++N;
6050 }
6051 }
6052
6053 if (!HadAvailAttr)
6054 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6055 return getCursorPlatformAvailabilityForDecl(
6056 cast<Decl>(EnumConst->getDeclContext()),
6057 always_deprecated,
6058 deprecated_message,
6059 always_unavailable,
6060 unavailable_message,
6061 availability,
6062 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006063
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006064 return N;
6065}
6066
Guy Benyei11169dd2012-12-18 14:30:41 +00006067int clang_getCursorPlatformAvailability(CXCursor cursor,
6068 int *always_deprecated,
6069 CXString *deprecated_message,
6070 int *always_unavailable,
6071 CXString *unavailable_message,
6072 CXPlatformAvailability *availability,
6073 int availability_size) {
6074 if (always_deprecated)
6075 *always_deprecated = 0;
6076 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006077 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006078 if (always_unavailable)
6079 *always_unavailable = 0;
6080 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006081 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006082
Guy Benyei11169dd2012-12-18 14:30:41 +00006083 if (!clang_isDeclaration(cursor.kind))
6084 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006085
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006086 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006087 if (!D)
6088 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006089
6090 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6091 deprecated_message,
6092 always_unavailable,
6093 unavailable_message,
6094 availability,
6095 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006096}
6097
6098void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6099 clang_disposeString(availability->Platform);
6100 clang_disposeString(availability->Message);
6101}
6102
6103CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6104 if (clang_isDeclaration(cursor.kind))
6105 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6106
6107 return CXLanguage_Invalid;
6108}
6109
6110 /// \brief If the given cursor is the "templated" declaration
6111 /// descibing a class or function template, return the class or
6112 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006113static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006114 if (!D)
6115 return 0;
6116
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006117 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006118 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6119 return FunTmpl;
6120
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006121 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006122 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6123 return ClassTmpl;
6124
6125 return D;
6126}
6127
6128CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6129 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006130 if (const Decl *D = getCursorDecl(cursor)) {
6131 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006132 if (!DC)
6133 return clang_getNullCursor();
6134
6135 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6136 getCursorTU(cursor));
6137 }
6138 }
6139
6140 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006141 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006142 return MakeCXCursor(D, getCursorTU(cursor));
6143 }
6144
6145 return clang_getNullCursor();
6146}
6147
6148CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6149 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006150 if (const Decl *D = getCursorDecl(cursor)) {
6151 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006152 if (!DC)
6153 return clang_getNullCursor();
6154
6155 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6156 getCursorTU(cursor));
6157 }
6158 }
6159
6160 // FIXME: Note that we can't easily compute the lexical context of a
6161 // statement or expression, so we return nothing.
6162 return clang_getNullCursor();
6163}
6164
6165CXFile clang_getIncludedFile(CXCursor cursor) {
6166 if (cursor.kind != CXCursor_InclusionDirective)
6167 return 0;
6168
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006169 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006170 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006171}
6172
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006173unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6174 if (C.kind != CXCursor_ObjCPropertyDecl)
6175 return CXObjCPropertyAttr_noattr;
6176
6177 unsigned Result = CXObjCPropertyAttr_noattr;
6178 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6179 ObjCPropertyDecl::PropertyAttributeKind Attr =
6180 PD->getPropertyAttributesAsWritten();
6181
6182#define SET_CXOBJCPROP_ATTR(A) \
6183 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6184 Result |= CXObjCPropertyAttr_##A
6185 SET_CXOBJCPROP_ATTR(readonly);
6186 SET_CXOBJCPROP_ATTR(getter);
6187 SET_CXOBJCPROP_ATTR(assign);
6188 SET_CXOBJCPROP_ATTR(readwrite);
6189 SET_CXOBJCPROP_ATTR(retain);
6190 SET_CXOBJCPROP_ATTR(copy);
6191 SET_CXOBJCPROP_ATTR(nonatomic);
6192 SET_CXOBJCPROP_ATTR(setter);
6193 SET_CXOBJCPROP_ATTR(atomic);
6194 SET_CXOBJCPROP_ATTR(weak);
6195 SET_CXOBJCPROP_ATTR(strong);
6196 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6197#undef SET_CXOBJCPROP_ATTR
6198
6199 return Result;
6200}
6201
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006202unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6203 if (!clang_isDeclaration(C.kind))
6204 return CXObjCDeclQualifier_None;
6205
6206 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6207 const Decl *D = getCursorDecl(C);
6208 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6209 QT = MD->getObjCDeclQualifier();
6210 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6211 QT = PD->getObjCDeclQualifier();
6212 if (QT == Decl::OBJC_TQ_None)
6213 return CXObjCDeclQualifier_None;
6214
6215 unsigned Result = CXObjCDeclQualifier_None;
6216 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6217 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6218 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6219 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6220 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6221 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6222
6223 return Result;
6224}
6225
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006226unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6227 if (!clang_isDeclaration(C.kind))
6228 return 0;
6229
6230 const Decl *D = getCursorDecl(C);
6231 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6232 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6233 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6234 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6235
6236 return 0;
6237}
6238
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006239unsigned clang_Cursor_isVariadic(CXCursor C) {
6240 if (!clang_isDeclaration(C.kind))
6241 return 0;
6242
6243 const Decl *D = getCursorDecl(C);
6244 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6245 return FD->isVariadic();
6246 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6247 return MD->isVariadic();
6248
6249 return 0;
6250}
6251
Guy Benyei11169dd2012-12-18 14:30:41 +00006252CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6253 if (!clang_isDeclaration(C.kind))
6254 return clang_getNullRange();
6255
6256 const Decl *D = getCursorDecl(C);
6257 ASTContext &Context = getCursorContext(C);
6258 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6259 if (!RC)
6260 return clang_getNullRange();
6261
6262 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6263}
6264
6265CXString clang_Cursor_getRawCommentText(CXCursor C) {
6266 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006267 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006268
6269 const Decl *D = getCursorDecl(C);
6270 ASTContext &Context = getCursorContext(C);
6271 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6272 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6273 StringRef();
6274
6275 // Don't duplicate the string because RawText points directly into source
6276 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006277 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006278}
6279
6280CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6281 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006282 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006283
6284 const Decl *D = getCursorDecl(C);
6285 const ASTContext &Context = getCursorContext(C);
6286 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6287
6288 if (RC) {
6289 StringRef BriefText = RC->getBriefText(Context);
6290
6291 // Don't duplicate the string because RawComment ensures that this memory
6292 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006293 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006294 }
6295
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006296 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006297}
6298
6299CXComment clang_Cursor_getParsedComment(CXCursor C) {
6300 if (!clang_isDeclaration(C.kind))
6301 return cxcomment::createCXComment(NULL, NULL);
6302
6303 const Decl *D = getCursorDecl(C);
6304 const ASTContext &Context = getCursorContext(C);
6305 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6306
6307 return cxcomment::createCXComment(FC, getCursorTU(C));
6308}
6309
6310CXModule clang_Cursor_getModule(CXCursor C) {
6311 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006312 if (const ImportDecl *ImportD =
6313 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006314 return ImportD->getImportedModule();
6315 }
6316
6317 return 0;
6318}
6319
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006320CXFile clang_Module_getASTFile(CXModule CXMod) {
6321 if (!CXMod)
6322 return 0;
6323 Module *Mod = static_cast<Module*>(CXMod);
6324 return const_cast<FileEntry *>(Mod->getASTFile());
6325}
6326
Guy Benyei11169dd2012-12-18 14:30:41 +00006327CXModule clang_Module_getParent(CXModule CXMod) {
6328 if (!CXMod)
6329 return 0;
6330 Module *Mod = static_cast<Module*>(CXMod);
6331 return Mod->Parent;
6332}
6333
6334CXString clang_Module_getName(CXModule CXMod) {
6335 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006336 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006337 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006338 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006339}
6340
6341CXString clang_Module_getFullName(CXModule CXMod) {
6342 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006343 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006344 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006345 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006346}
6347
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006348unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6349 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006350 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006351 LOG_BAD_TU(TU);
6352 return 0;
6353 }
6354 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006355 return 0;
6356 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006357 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6358 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6359 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006360}
6361
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006362CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6363 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006364 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006365 LOG_BAD_TU(TU);
6366 return 0;
6367 }
6368 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006369 return 0;
6370 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006371 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006372
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006373 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6374 if (Index < TopHeaders.size())
6375 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006376
6377 return 0;
6378}
6379
6380} // end: extern "C"
6381
6382//===----------------------------------------------------------------------===//
6383// C++ AST instrospection.
6384//===----------------------------------------------------------------------===//
6385
6386extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006387unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6388 if (!clang_isDeclaration(C.kind))
6389 return 0;
6390
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006391 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006392 const CXXMethodDecl *Method =
6393 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006394 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6395}
6396
Guy Benyei11169dd2012-12-18 14:30:41 +00006397unsigned clang_CXXMethod_isStatic(CXCursor C) {
6398 if (!clang_isDeclaration(C.kind))
6399 return 0;
6400
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006401 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006402 const CXXMethodDecl *Method =
6403 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006404 return (Method && Method->isStatic()) ? 1 : 0;
6405}
6406
6407unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6408 if (!clang_isDeclaration(C.kind))
6409 return 0;
6410
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006411 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006412 const CXXMethodDecl *Method =
6413 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006414 return (Method && Method->isVirtual()) ? 1 : 0;
6415}
6416} // end: extern "C"
6417
6418//===----------------------------------------------------------------------===//
6419// Attribute introspection.
6420//===----------------------------------------------------------------------===//
6421
6422extern "C" {
6423CXType clang_getIBOutletCollectionType(CXCursor C) {
6424 if (C.kind != CXCursor_IBOutletCollectionAttr)
6425 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6426
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006427 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006428 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6429
6430 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6431}
6432} // end: extern "C"
6433
6434//===----------------------------------------------------------------------===//
6435// Inspecting memory usage.
6436//===----------------------------------------------------------------------===//
6437
6438typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6439
6440static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6441 enum CXTUResourceUsageKind k,
6442 unsigned long amount) {
6443 CXTUResourceUsageEntry entry = { k, amount };
6444 entries.push_back(entry);
6445}
6446
6447extern "C" {
6448
6449const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6450 const char *str = "";
6451 switch (kind) {
6452 case CXTUResourceUsage_AST:
6453 str = "ASTContext: expressions, declarations, and types";
6454 break;
6455 case CXTUResourceUsage_Identifiers:
6456 str = "ASTContext: identifiers";
6457 break;
6458 case CXTUResourceUsage_Selectors:
6459 str = "ASTContext: selectors";
6460 break;
6461 case CXTUResourceUsage_GlobalCompletionResults:
6462 str = "Code completion: cached global results";
6463 break;
6464 case CXTUResourceUsage_SourceManagerContentCache:
6465 str = "SourceManager: content cache allocator";
6466 break;
6467 case CXTUResourceUsage_AST_SideTables:
6468 str = "ASTContext: side tables";
6469 break;
6470 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6471 str = "SourceManager: malloc'ed memory buffers";
6472 break;
6473 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6474 str = "SourceManager: mmap'ed memory buffers";
6475 break;
6476 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6477 str = "ExternalASTSource: malloc'ed memory buffers";
6478 break;
6479 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6480 str = "ExternalASTSource: mmap'ed memory buffers";
6481 break;
6482 case CXTUResourceUsage_Preprocessor:
6483 str = "Preprocessor: malloc'ed memory";
6484 break;
6485 case CXTUResourceUsage_PreprocessingRecord:
6486 str = "Preprocessor: PreprocessingRecord";
6487 break;
6488 case CXTUResourceUsage_SourceManager_DataStructures:
6489 str = "SourceManager: data structures and tables";
6490 break;
6491 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6492 str = "Preprocessor: header search tables";
6493 break;
6494 }
6495 return str;
6496}
6497
6498CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006499 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006500 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006501 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6502 return usage;
6503 }
6504
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006505 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006506 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6507 ASTContext &astContext = astUnit->getASTContext();
6508
6509 // How much memory is used by AST nodes and types?
6510 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6511 (unsigned long) astContext.getASTAllocatedMemory());
6512
6513 // How much memory is used by identifiers?
6514 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6515 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6516
6517 // How much memory is used for selectors?
6518 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6519 (unsigned long) astContext.Selectors.getTotalMemory());
6520
6521 // How much memory is used by ASTContext's side tables?
6522 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6523 (unsigned long) astContext.getSideTableAllocatedMemory());
6524
6525 // How much memory is used for caching global code completion results?
6526 unsigned long completionBytes = 0;
6527 if (GlobalCodeCompletionAllocator *completionAllocator =
6528 astUnit->getCachedCompletionAllocator().getPtr()) {
6529 completionBytes = completionAllocator->getTotalMemory();
6530 }
6531 createCXTUResourceUsageEntry(*entries,
6532 CXTUResourceUsage_GlobalCompletionResults,
6533 completionBytes);
6534
6535 // How much memory is being used by SourceManager's content cache?
6536 createCXTUResourceUsageEntry(*entries,
6537 CXTUResourceUsage_SourceManagerContentCache,
6538 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6539
6540 // How much memory is being used by the MemoryBuffer's in SourceManager?
6541 const SourceManager::MemoryBufferSizes &srcBufs =
6542 astUnit->getSourceManager().getMemoryBufferSizes();
6543
6544 createCXTUResourceUsageEntry(*entries,
6545 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6546 (unsigned long) srcBufs.malloc_bytes);
6547 createCXTUResourceUsageEntry(*entries,
6548 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6549 (unsigned long) srcBufs.mmap_bytes);
6550 createCXTUResourceUsageEntry(*entries,
6551 CXTUResourceUsage_SourceManager_DataStructures,
6552 (unsigned long) astContext.getSourceManager()
6553 .getDataStructureSizes());
6554
6555 // How much memory is being used by the ExternalASTSource?
6556 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6557 const ExternalASTSource::MemoryBufferSizes &sizes =
6558 esrc->getMemoryBufferSizes();
6559
6560 createCXTUResourceUsageEntry(*entries,
6561 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6562 (unsigned long) sizes.malloc_bytes);
6563 createCXTUResourceUsageEntry(*entries,
6564 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6565 (unsigned long) sizes.mmap_bytes);
6566 }
6567
6568 // How much memory is being used by the Preprocessor?
6569 Preprocessor &pp = astUnit->getPreprocessor();
6570 createCXTUResourceUsageEntry(*entries,
6571 CXTUResourceUsage_Preprocessor,
6572 pp.getTotalMemory());
6573
6574 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6575 createCXTUResourceUsageEntry(*entries,
6576 CXTUResourceUsage_PreprocessingRecord,
6577 pRec->getTotalMemory());
6578 }
6579
6580 createCXTUResourceUsageEntry(*entries,
6581 CXTUResourceUsage_Preprocessor_HeaderSearch,
6582 pp.getHeaderSearchInfo().getTotalMemory());
6583
6584 CXTUResourceUsage usage = { (void*) entries.get(),
6585 (unsigned) entries->size(),
6586 entries->size() ? &(*entries)[0] : 0 };
6587 entries.take();
6588 return usage;
6589}
6590
6591void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6592 if (usage.data)
6593 delete (MemUsageEntries*) usage.data;
6594}
6595
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006596CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6597 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006598 skipped->count = 0;
6599 skipped->ranges = 0;
6600
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006601 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006602 LOG_BAD_TU(TU);
6603 return skipped;
6604 }
6605
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006606 if (!file)
6607 return skipped;
6608
6609 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6610 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6611 if (!ppRec)
6612 return skipped;
6613
6614 ASTContext &Ctx = astUnit->getASTContext();
6615 SourceManager &sm = Ctx.getSourceManager();
6616 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6617 FileID wantedFileID = sm.translateFile(fileEntry);
6618
6619 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6620 std::vector<SourceRange> wantedRanges;
6621 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6622 i != ei; ++i) {
6623 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6624 wantedRanges.push_back(*i);
6625 }
6626
6627 skipped->count = wantedRanges.size();
6628 skipped->ranges = new CXSourceRange[skipped->count];
6629 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6630 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6631
6632 return skipped;
6633}
6634
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006635void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6636 if (ranges) {
6637 delete[] ranges->ranges;
6638 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006639 }
6640}
6641
Guy Benyei11169dd2012-12-18 14:30:41 +00006642} // end extern "C"
6643
6644void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6645 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6646 for (unsigned I = 0; I != Usage.numEntries; ++I)
6647 fprintf(stderr, " %s: %lu\n",
6648 clang_getTUResourceUsageName(Usage.entries[I].kind),
6649 Usage.entries[I].amount);
6650
6651 clang_disposeCXTUResourceUsage(Usage);
6652}
6653
6654//===----------------------------------------------------------------------===//
6655// Misc. utility functions.
6656//===----------------------------------------------------------------------===//
6657
6658/// Default to using an 8 MB stack size on "safety" threads.
6659static unsigned SafetyStackThreadSize = 8 << 20;
6660
6661namespace clang {
6662
6663bool RunSafely(llvm::CrashRecoveryContext &CRC,
6664 void (*Fn)(void*), void *UserData,
6665 unsigned Size) {
6666 if (!Size)
6667 Size = GetSafetyThreadStackSize();
6668 if (Size)
6669 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6670 return CRC.RunSafely(Fn, UserData);
6671}
6672
6673unsigned GetSafetyThreadStackSize() {
6674 return SafetyStackThreadSize;
6675}
6676
6677void SetSafetyThreadStackSize(unsigned Value) {
6678 SafetyStackThreadSize = Value;
6679}
6680
6681}
6682
6683void clang::setThreadBackgroundPriority() {
6684 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6685 return;
6686
6687 // FIXME: Move to llvm/Support and make it cross-platform.
6688#ifdef __APPLE__
6689 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6690#endif
6691}
6692
6693void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6694 if (!Unit)
6695 return;
6696
6697 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6698 DEnd = Unit->stored_diag_end();
6699 D != DEnd; ++D) {
6700 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6701 CXString Msg = clang_formatDiagnostic(&Diag,
6702 clang_defaultDiagnosticDisplayOptions());
6703 fprintf(stderr, "%s\n", clang_getCString(Msg));
6704 clang_disposeString(Msg);
6705 }
6706#ifdef LLVM_ON_WIN32
6707 // On Windows, force a flush, since there may be multiple copies of
6708 // stderr and stdout in the file system, all with different buffers
6709 // but writing to the same device.
6710 fflush(stderr);
6711#endif
6712}
6713
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006714MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6715 SourceLocation MacroDefLoc,
6716 CXTranslationUnit TU){
6717 if (MacroDefLoc.isInvalid() || !TU)
6718 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006719 if (!II.hadMacroDefinition())
6720 return 0;
6721
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006722 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006723 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006724 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006725 if (MD) {
6726 for (MacroDirective::DefInfo
6727 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6728 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6729 return Def.getMacroInfo();
6730 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006731 }
6732
6733 return 0;
6734}
6735
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006736const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6737 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006738 if (!MacroDef || !TU)
6739 return 0;
6740 const IdentifierInfo *II = MacroDef->getName();
6741 if (!II)
6742 return 0;
6743
6744 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6745}
6746
6747MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6748 const Token &Tok,
6749 CXTranslationUnit TU) {
6750 if (!MI || !TU)
6751 return 0;
6752 if (Tok.isNot(tok::raw_identifier))
6753 return 0;
6754
6755 if (MI->getNumTokens() == 0)
6756 return 0;
6757 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6758 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006759 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006760
6761 // Check that the token is inside the definition and not its argument list.
6762 SourceManager &SM = Unit->getSourceManager();
6763 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6764 return 0;
6765 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6766 return 0;
6767
6768 Preprocessor &PP = Unit->getPreprocessor();
6769 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6770 if (!PPRec)
6771 return 0;
6772
6773 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6774 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6775 if (!II.hadMacroDefinition())
6776 return 0;
6777
6778 // Check that the identifier is not one of the macro arguments.
6779 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6780 return 0;
6781
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006782 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6783 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006784 return 0;
6785
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006786 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006787}
6788
6789MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6790 SourceLocation Loc,
6791 CXTranslationUnit TU) {
6792 if (Loc.isInvalid() || !MI || !TU)
6793 return 0;
6794
6795 if (MI->getNumTokens() == 0)
6796 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006797 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006798 Preprocessor &PP = Unit->getPreprocessor();
6799 if (!PP.getPreprocessingRecord())
6800 return 0;
6801 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6802 Token Tok;
6803 if (PP.getRawToken(Loc, Tok))
6804 return 0;
6805
6806 return checkForMacroInMacroDefinition(MI, Tok, TU);
6807}
6808
Guy Benyei11169dd2012-12-18 14:30:41 +00006809extern "C" {
6810
6811CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006812 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006813}
6814
6815} // end: extern "C"
6816
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006817Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6818 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006819 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006820 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006821 if (Unit->isMainFileAST())
6822 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006823 return *this;
6824 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006825 } else {
6826 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006827 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006828 return *this;
6829}
6830
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006831Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6832 *this << FE->getName();
6833 return *this;
6834}
6835
6836Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6837 CXString cursorName = clang_getCursorDisplayName(cursor);
6838 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6839 clang_disposeString(cursorName);
6840 return *this;
6841}
6842
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006843Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6844 CXFile File;
6845 unsigned Line, Column;
6846 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6847 CXString FileName = clang_getFileName(File);
6848 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6849 clang_disposeString(FileName);
6850 return *this;
6851}
6852
6853Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6854 CXSourceLocation BLoc = clang_getRangeStart(range);
6855 CXSourceLocation ELoc = clang_getRangeEnd(range);
6856
6857 CXFile BFile;
6858 unsigned BLine, BColumn;
6859 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6860
6861 CXFile EFile;
6862 unsigned ELine, EColumn;
6863 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6864
6865 CXString BFileName = clang_getFileName(BFile);
6866 if (BFile == EFile) {
6867 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6868 BLine, BColumn, ELine, EColumn);
6869 } else {
6870 CXString EFileName = clang_getFileName(EFile);
6871 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6872 BLine, BColumn)
6873 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6874 ELine, EColumn);
6875 clang_disposeString(EFileName);
6876 }
6877 clang_disposeString(BFileName);
6878 return *this;
6879}
6880
6881Logger &cxindex::Logger::operator<<(CXString Str) {
6882 *this << clang_getCString(Str);
6883 return *this;
6884}
6885
6886Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6887 LogOS << Fmt;
6888 return *this;
6889}
6890
6891cxindex::Logger::~Logger() {
6892 LogOS.flush();
6893
6894 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6895
6896 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6897
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006898 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006899 OS << "[libclang:" << Name << ':';
6900
6901 // FIXME: Portability.
6902#if HAVE_PTHREAD_H && __APPLE__
6903 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6904 OS << tid << ':';
6905#endif
6906
6907 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6908 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6909 OS << Msg.str() << '\n';
6910
6911 if (Trace) {
6912 llvm::sys::PrintStackTrace(stderr);
6913 OS << "--------------------------------------------------\n";
6914 }
6915}