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