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