blob: 864b753b05902d0bb0d4de7595ccc270a7c91105 [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
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000317 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000318 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
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000765/// \brief Compare two base or member initializers based on their source order.
766static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
767 CXXCtorInitializer *const *Y) {
768 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
769}
770
Guy Benyei11169dd2012-12-18 14:30:41 +0000771bool 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;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000815 for (auto *I : Constructor->inits()) {
816 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000817 continue;
818
Aaron Ballman0ad78302014-03-13 17:34:31 +0000819 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000820 }
821
822 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000823 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
824 &CompareCXXCtorInitializers);
825
Guy Benyei11169dd2012-12-18 14:30:41 +0000826 // Visit the initializers in source order
827 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
828 CXXCtorInitializer *Init = WrittenInits[I];
829 if (Init->isAnyMemberInitializer()) {
830 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
831 Init->getMemberLocation(), TU)))
832 return true;
833 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
834 if (Visit(TInfo->getTypeLoc()))
835 return true;
836 }
837
838 // Visit the initializer value.
839 if (Expr *Initializer = Init->getInit())
840 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
841 return true;
842 }
843 }
844
845 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
846 return true;
847 }
848
849 return false;
850}
851
852bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
853 if (VisitDeclaratorDecl(D))
854 return true;
855
856 if (Expr *BitWidth = D->getBitWidth())
857 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
858
859 return false;
860}
861
862bool CursorVisitor::VisitVarDecl(VarDecl *D) {
863 if (VisitDeclaratorDecl(D))
864 return true;
865
866 if (Expr *Init = D->getInit())
867 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
868
869 return false;
870}
871
872bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
873 if (VisitDeclaratorDecl(D))
874 return true;
875
876 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
877 if (Expr *DefArg = D->getDefaultArgument())
878 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
879
880 return false;
881}
882
883bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
884 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
885 // before visiting these template parameters.
886 if (VisitTemplateParameters(D->getTemplateParameters()))
887 return true;
888
889 return VisitFunctionDecl(D->getTemplatedDecl());
890}
891
892bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
893 // FIXME: Visit the "outer" template parameter lists on the TagDecl
894 // before visiting these template parameters.
895 if (VisitTemplateParameters(D->getTemplateParameters()))
896 return true;
897
898 return VisitCXXRecordDecl(D->getTemplatedDecl());
899}
900
901bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
902 if (VisitTemplateParameters(D->getTemplateParameters()))
903 return true;
904
905 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
906 VisitTemplateArgumentLoc(D->getDefaultArgument()))
907 return true;
908
909 return false;
910}
911
912bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000913 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000914 if (Visit(TSInfo->getTypeLoc()))
915 return true;
916
Aaron Ballman43b68be2014-03-07 17:50:17 +0000917 for (const auto *P : ND->params()) {
918 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000919 return true;
920 }
921
922 if (ND->isThisDeclarationADefinition() &&
923 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
924 return true;
925
926 return false;
927}
928
929template <typename DeclIt>
930static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
931 SourceManager &SM, SourceLocation EndLoc,
932 SmallVectorImpl<Decl *> &Decls) {
933 DeclIt next = *DI_current;
934 while (++next != DE_current) {
935 Decl *D_next = *next;
936 if (!D_next)
937 break;
938 SourceLocation L = D_next->getLocStart();
939 if (!L.isValid())
940 break;
941 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
942 *DI_current = next;
943 Decls.push_back(D_next);
944 continue;
945 }
946 break;
947 }
948}
949
Guy Benyei11169dd2012-12-18 14:30:41 +0000950bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
951 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
952 // an @implementation can lexically contain Decls that are not properly
953 // nested in the AST. When we identify such cases, we need to retrofit
954 // this nesting here.
955 if (!DI_current && !FileDI_current)
956 return VisitDeclContext(D);
957
958 // Scan the Decls that immediately come after the container
959 // in the current DeclContext. If any fall within the
960 // container's lexical region, stash them into a vector
961 // for later processing.
962 SmallVector<Decl *, 24> DeclsInContainer;
963 SourceLocation EndLoc = D->getSourceRange().getEnd();
964 SourceManager &SM = AU->getSourceManager();
965 if (EndLoc.isValid()) {
966 if (DI_current) {
967 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
968 DeclsInContainer);
969 } else {
970 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
971 DeclsInContainer);
972 }
973 }
974
975 // The common case.
976 if (DeclsInContainer.empty())
977 return VisitDeclContext(D);
978
979 // Get all the Decls in the DeclContext, and sort them with the
980 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000981 for (auto *SubDecl : D->decls()) {
982 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
983 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000984 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000985 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000986 }
987
988 // Now sort the Decls so that they appear in lexical order.
989 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000990 [&SM](Decl *A, Decl *B) {
991 SourceLocation L_A = A->getLocStart();
992 SourceLocation L_B = B->getLocStart();
993 assert(L_A.isValid() && L_B.isValid());
994 return SM.isBeforeInTranslationUnit(L_A, L_B);
995 });
Guy Benyei11169dd2012-12-18 14:30:41 +0000996
997 // Now visit the decls.
998 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
999 E = DeclsInContainer.end(); I != E; ++I) {
1000 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001001 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001002 if (!V.hasValue())
1003 continue;
1004 if (!V.getValue())
1005 return false;
1006 if (Visit(Cursor, true))
1007 return true;
1008 }
1009 return false;
1010}
1011
1012bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1013 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1014 TU)))
1015 return true;
1016
1017 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1018 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1019 E = ND->protocol_end(); I != E; ++I, ++PL)
1020 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1021 return true;
1022
1023 return VisitObjCContainerDecl(ND);
1024}
1025
1026bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1027 if (!PID->isThisDeclarationADefinition())
1028 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1029
1030 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1031 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1032 E = PID->protocol_end(); I != E; ++I, ++PL)
1033 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1034 return true;
1035
1036 return VisitObjCContainerDecl(PID);
1037}
1038
1039bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1040 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1041 return true;
1042
1043 // FIXME: This implements a workaround with @property declarations also being
1044 // installed in the DeclContext for the @interface. Eventually this code
1045 // should be removed.
1046 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1047 if (!CDecl || !CDecl->IsClassExtension())
1048 return false;
1049
1050 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1051 if (!ID)
1052 return false;
1053
1054 IdentifierInfo *PropertyId = PD->getIdentifier();
1055 ObjCPropertyDecl *prevDecl =
1056 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1057
1058 if (!prevDecl)
1059 return false;
1060
1061 // Visit synthesized methods since they will be skipped when visiting
1062 // the @interface.
1063 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1064 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1065 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1066 return true;
1067
1068 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1069 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1070 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1071 return true;
1072
1073 return false;
1074}
1075
1076bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1077 if (!D->isThisDeclarationADefinition()) {
1078 // Forward declaration is treated like a reference.
1079 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1080 }
1081
1082 // Issue callbacks for super class.
1083 if (D->getSuperClass() &&
1084 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1085 D->getSuperClassLoc(),
1086 TU)))
1087 return true;
1088
1089 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1090 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1091 E = D->protocol_end(); I != E; ++I, ++PL)
1092 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1093 return true;
1094
1095 return VisitObjCContainerDecl(D);
1096}
1097
1098bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1099 return VisitObjCContainerDecl(D);
1100}
1101
1102bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1103 // 'ID' could be null when dealing with invalid code.
1104 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1105 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1106 return true;
1107
1108 return VisitObjCImplDecl(D);
1109}
1110
1111bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1112#if 0
1113 // Issue callbacks for super class.
1114 // FIXME: No source location information!
1115 if (D->getSuperClass() &&
1116 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1117 D->getSuperClassLoc(),
1118 TU)))
1119 return true;
1120#endif
1121
1122 return VisitObjCImplDecl(D);
1123}
1124
1125bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1126 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1127 if (PD->isIvarNameSpecified())
1128 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1129
1130 return false;
1131}
1132
1133bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1134 return VisitDeclContext(D);
1135}
1136
1137bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1138 // Visit nested-name-specifier.
1139 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1140 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1141 return true;
1142
1143 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1144 D->getTargetNameLoc(), TU));
1145}
1146
1147bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1148 // Visit nested-name-specifier.
1149 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1150 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1151 return true;
1152 }
1153
1154 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1155 return true;
1156
1157 return VisitDeclarationNameInfo(D->getNameInfo());
1158}
1159
1160bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1161 // Visit nested-name-specifier.
1162 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1163 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1164 return true;
1165
1166 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1167 D->getIdentLocation(), TU));
1168}
1169
1170bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1171 // Visit nested-name-specifier.
1172 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1173 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1174 return true;
1175 }
1176
1177 return VisitDeclarationNameInfo(D->getNameInfo());
1178}
1179
1180bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1181 UnresolvedUsingTypenameDecl *D) {
1182 // Visit nested-name-specifier.
1183 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1184 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1185 return true;
1186
1187 return false;
1188}
1189
1190bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1191 switch (Name.getName().getNameKind()) {
1192 case clang::DeclarationName::Identifier:
1193 case clang::DeclarationName::CXXLiteralOperatorName:
1194 case clang::DeclarationName::CXXOperatorName:
1195 case clang::DeclarationName::CXXUsingDirective:
1196 return false;
1197
1198 case clang::DeclarationName::CXXConstructorName:
1199 case clang::DeclarationName::CXXDestructorName:
1200 case clang::DeclarationName::CXXConversionFunctionName:
1201 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1202 return Visit(TSInfo->getTypeLoc());
1203 return false;
1204
1205 case clang::DeclarationName::ObjCZeroArgSelector:
1206 case clang::DeclarationName::ObjCOneArgSelector:
1207 case clang::DeclarationName::ObjCMultiArgSelector:
1208 // FIXME: Per-identifier location info?
1209 return false;
1210 }
1211
1212 llvm_unreachable("Invalid DeclarationName::Kind!");
1213}
1214
1215bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1216 SourceRange Range) {
1217 // FIXME: This whole routine is a hack to work around the lack of proper
1218 // source information in nested-name-specifiers (PR5791). Since we do have
1219 // a beginning source location, we can visit the first component of the
1220 // nested-name-specifier, if it's a single-token component.
1221 if (!NNS)
1222 return false;
1223
1224 // Get the first component in the nested-name-specifier.
1225 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1226 NNS = Prefix;
1227
1228 switch (NNS->getKind()) {
1229 case NestedNameSpecifier::Namespace:
1230 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1231 TU));
1232
1233 case NestedNameSpecifier::NamespaceAlias:
1234 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1235 Range.getBegin(), TU));
1236
1237 case NestedNameSpecifier::TypeSpec: {
1238 // If the type has a form where we know that the beginning of the source
1239 // range matches up with a reference cursor. Visit the appropriate reference
1240 // cursor.
1241 const Type *T = NNS->getAsType();
1242 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1243 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1244 if (const TagType *Tag = dyn_cast<TagType>(T))
1245 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1246 if (const TemplateSpecializationType *TST
1247 = dyn_cast<TemplateSpecializationType>(T))
1248 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1249 break;
1250 }
1251
1252 case NestedNameSpecifier::TypeSpecWithTemplate:
1253 case NestedNameSpecifier::Global:
1254 case NestedNameSpecifier::Identifier:
1255 break;
1256 }
1257
1258 return false;
1259}
1260
1261bool
1262CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1263 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1264 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1265 Qualifiers.push_back(Qualifier);
1266
1267 while (!Qualifiers.empty()) {
1268 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1269 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1270 switch (NNS->getKind()) {
1271 case NestedNameSpecifier::Namespace:
1272 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1273 Q.getLocalBeginLoc(),
1274 TU)))
1275 return true;
1276
1277 break;
1278
1279 case NestedNameSpecifier::NamespaceAlias:
1280 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1281 Q.getLocalBeginLoc(),
1282 TU)))
1283 return true;
1284
1285 break;
1286
1287 case NestedNameSpecifier::TypeSpec:
1288 case NestedNameSpecifier::TypeSpecWithTemplate:
1289 if (Visit(Q.getTypeLoc()))
1290 return true;
1291
1292 break;
1293
1294 case NestedNameSpecifier::Global:
1295 case NestedNameSpecifier::Identifier:
1296 break;
1297 }
1298 }
1299
1300 return false;
1301}
1302
1303bool CursorVisitor::VisitTemplateParameters(
1304 const TemplateParameterList *Params) {
1305 if (!Params)
1306 return false;
1307
1308 for (TemplateParameterList::const_iterator P = Params->begin(),
1309 PEnd = Params->end();
1310 P != PEnd; ++P) {
1311 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1312 return true;
1313 }
1314
1315 return false;
1316}
1317
1318bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1319 switch (Name.getKind()) {
1320 case TemplateName::Template:
1321 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1322
1323 case TemplateName::OverloadedTemplate:
1324 // Visit the overloaded template set.
1325 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1326 return true;
1327
1328 return false;
1329
1330 case TemplateName::DependentTemplate:
1331 // FIXME: Visit nested-name-specifier.
1332 return false;
1333
1334 case TemplateName::QualifiedTemplate:
1335 // FIXME: Visit nested-name-specifier.
1336 return Visit(MakeCursorTemplateRef(
1337 Name.getAsQualifiedTemplateName()->getDecl(),
1338 Loc, TU));
1339
1340 case TemplateName::SubstTemplateTemplateParm:
1341 return Visit(MakeCursorTemplateRef(
1342 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1343 Loc, TU));
1344
1345 case TemplateName::SubstTemplateTemplateParmPack:
1346 return Visit(MakeCursorTemplateRef(
1347 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1348 Loc, TU));
1349 }
1350
1351 llvm_unreachable("Invalid TemplateName::Kind!");
1352}
1353
1354bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1355 switch (TAL.getArgument().getKind()) {
1356 case TemplateArgument::Null:
1357 case TemplateArgument::Integral:
1358 case TemplateArgument::Pack:
1359 return false;
1360
1361 case TemplateArgument::Type:
1362 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1363 return Visit(TSInfo->getTypeLoc());
1364 return false;
1365
1366 case TemplateArgument::Declaration:
1367 if (Expr *E = TAL.getSourceDeclExpression())
1368 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1369 return false;
1370
1371 case TemplateArgument::NullPtr:
1372 if (Expr *E = TAL.getSourceNullPtrExpression())
1373 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1374 return false;
1375
1376 case TemplateArgument::Expression:
1377 if (Expr *E = TAL.getSourceExpression())
1378 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1379 return false;
1380
1381 case TemplateArgument::Template:
1382 case TemplateArgument::TemplateExpansion:
1383 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1384 return true;
1385
1386 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1387 TAL.getTemplateNameLoc());
1388 }
1389
1390 llvm_unreachable("Invalid TemplateArgument::Kind!");
1391}
1392
1393bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1394 return VisitDeclContext(D);
1395}
1396
1397bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1398 return Visit(TL.getUnqualifiedLoc());
1399}
1400
1401bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1402 ASTContext &Context = AU->getASTContext();
1403
1404 // Some builtin types (such as Objective-C's "id", "sel", and
1405 // "Class") have associated declarations. Create cursors for those.
1406 QualType VisitType;
1407 switch (TL.getTypePtr()->getKind()) {
1408
1409 case BuiltinType::Void:
1410 case BuiltinType::NullPtr:
1411 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001412 case BuiltinType::OCLImage1d:
1413 case BuiltinType::OCLImage1dArray:
1414 case BuiltinType::OCLImage1dBuffer:
1415 case BuiltinType::OCLImage2d:
1416 case BuiltinType::OCLImage2dArray:
1417 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001418 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001419 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001420#define BUILTIN_TYPE(Id, SingletonId)
1421#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1422#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1423#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1424#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1425#include "clang/AST/BuiltinTypes.def"
1426 break;
1427
1428 case BuiltinType::ObjCId:
1429 VisitType = Context.getObjCIdType();
1430 break;
1431
1432 case BuiltinType::ObjCClass:
1433 VisitType = Context.getObjCClassType();
1434 break;
1435
1436 case BuiltinType::ObjCSel:
1437 VisitType = Context.getObjCSelType();
1438 break;
1439 }
1440
1441 if (!VisitType.isNull()) {
1442 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1443 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1444 TU));
1445 }
1446
1447 return false;
1448}
1449
1450bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1451 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1452}
1453
1454bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1455 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1456}
1457
1458bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1459 if (TL.isDefinition())
1460 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1461
1462 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1463}
1464
1465bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1466 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1467}
1468
1469bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1470 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1471 return true;
1472
1473 return false;
1474}
1475
1476bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1477 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1478 return true;
1479
1480 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1481 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1482 TU)))
1483 return true;
1484 }
1485
1486 return false;
1487}
1488
1489bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1490 return Visit(TL.getPointeeLoc());
1491}
1492
1493bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1494 return Visit(TL.getInnerLoc());
1495}
1496
1497bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1498 return Visit(TL.getPointeeLoc());
1499}
1500
1501bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1502 return Visit(TL.getPointeeLoc());
1503}
1504
1505bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1506 return Visit(TL.getPointeeLoc());
1507}
1508
1509bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1510 return Visit(TL.getPointeeLoc());
1511}
1512
1513bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1514 return Visit(TL.getPointeeLoc());
1515}
1516
1517bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1518 return Visit(TL.getModifiedLoc());
1519}
1520
1521bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1522 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001523 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001524 return true;
1525
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001526 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1527 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001528 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1529 return true;
1530
1531 return false;
1532}
1533
1534bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1535 if (Visit(TL.getElementLoc()))
1536 return true;
1537
1538 if (Expr *Size = TL.getSizeExpr())
1539 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1540
1541 return false;
1542}
1543
Reid Kleckner8a365022013-06-24 17:51:48 +00001544bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1545 return Visit(TL.getOriginalLoc());
1546}
1547
Reid Kleckner0503a872013-12-05 01:23:43 +00001548bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1549 return Visit(TL.getOriginalLoc());
1550}
1551
Guy Benyei11169dd2012-12-18 14:30:41 +00001552bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1553 TemplateSpecializationTypeLoc TL) {
1554 // Visit the template name.
1555 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1556 TL.getTemplateNameLoc()))
1557 return true;
1558
1559 // Visit the template arguments.
1560 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1561 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1562 return true;
1563
1564 return false;
1565}
1566
1567bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1568 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1569}
1570
1571bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1572 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1573 return Visit(TSInfo->getTypeLoc());
1574
1575 return false;
1576}
1577
1578bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1579 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1580 return Visit(TSInfo->getTypeLoc());
1581
1582 return false;
1583}
1584
1585bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1586 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1587 return true;
1588
1589 return false;
1590}
1591
1592bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1593 DependentTemplateSpecializationTypeLoc TL) {
1594 // Visit the nested-name-specifier, if there is one.
1595 if (TL.getQualifierLoc() &&
1596 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1597 return true;
1598
1599 // Visit the template arguments.
1600 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1601 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1602 return true;
1603
1604 return false;
1605}
1606
1607bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1608 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1609 return true;
1610
1611 return Visit(TL.getNamedTypeLoc());
1612}
1613
1614bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1615 return Visit(TL.getPatternLoc());
1616}
1617
1618bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1619 if (Expr *E = TL.getUnderlyingExpr())
1620 return Visit(MakeCXCursor(E, StmtParent, TU));
1621
1622 return false;
1623}
1624
1625bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1626 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1627}
1628
1629bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1630 return Visit(TL.getValueLoc());
1631}
1632
1633#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1634bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1635 return Visit##PARENT##Loc(TL); \
1636}
1637
1638DEFAULT_TYPELOC_IMPL(Complex, Type)
1639DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1640DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1641DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1642DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1643DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1644DEFAULT_TYPELOC_IMPL(Vector, Type)
1645DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1646DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1647DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1648DEFAULT_TYPELOC_IMPL(Record, TagType)
1649DEFAULT_TYPELOC_IMPL(Enum, TagType)
1650DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1651DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1652DEFAULT_TYPELOC_IMPL(Auto, Type)
1653
1654bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1655 // Visit the nested-name-specifier, if present.
1656 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1657 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1658 return true;
1659
1660 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001661 for (const auto &I : D->bases()) {
1662 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001663 return true;
1664 }
1665 }
1666
1667 return VisitTagDecl(D);
1668}
1669
1670bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001671 for (const auto *I : D->attrs())
1672 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001673 return true;
1674
1675 return false;
1676}
1677
1678//===----------------------------------------------------------------------===//
1679// Data-recursive visitor methods.
1680//===----------------------------------------------------------------------===//
1681
1682namespace {
1683#define DEF_JOB(NAME, DATA, KIND)\
1684class NAME : public VisitorJob {\
1685public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001686 NAME(const DATA *d, CXCursor parent) : \
1687 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001688 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001689 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001690};
1691
1692DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1693DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1694DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1695DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1696DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1697 ExplicitTemplateArgsVisitKind)
1698DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1699DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1700DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1701#undef DEF_JOB
1702
1703class DeclVisit : public VisitorJob {
1704public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001705 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001706 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001707 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001708 static bool classof(const VisitorJob *VJ) {
1709 return VJ->getKind() == DeclVisitKind;
1710 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001711 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001712 bool isFirst() const { return data[1] ? true : false; }
1713};
1714class TypeLocVisit : public VisitorJob {
1715public:
1716 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1717 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1718 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1719
1720 static bool classof(const VisitorJob *VJ) {
1721 return VJ->getKind() == TypeLocVisitKind;
1722 }
1723
1724 TypeLoc get() const {
1725 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001726 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001727 }
1728};
1729
1730class LabelRefVisit : public VisitorJob {
1731public:
1732 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1733 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1734 labelLoc.getPtrEncoding()) {}
1735
1736 static bool classof(const VisitorJob *VJ) {
1737 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1738 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001739 const LabelDecl *get() const {
1740 return static_cast<const LabelDecl *>(data[0]);
1741 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001742 SourceLocation getLoc() const {
1743 return SourceLocation::getFromPtrEncoding(data[1]); }
1744};
1745
1746class NestedNameSpecifierLocVisit : public VisitorJob {
1747public:
1748 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1749 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1750 Qualifier.getNestedNameSpecifier(),
1751 Qualifier.getOpaqueData()) { }
1752
1753 static bool classof(const VisitorJob *VJ) {
1754 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1755 }
1756
1757 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001758 return NestedNameSpecifierLoc(
1759 const_cast<NestedNameSpecifier *>(
1760 static_cast<const NestedNameSpecifier *>(data[0])),
1761 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001762 }
1763};
1764
1765class DeclarationNameInfoVisit : public VisitorJob {
1766public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001767 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001768 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001769 static bool classof(const VisitorJob *VJ) {
1770 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1771 }
1772 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001773 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001774 switch (S->getStmtClass()) {
1775 default:
1776 llvm_unreachable("Unhandled Stmt");
1777 case clang::Stmt::MSDependentExistsStmtClass:
1778 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1779 case Stmt::CXXDependentScopeMemberExprClass:
1780 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1781 case Stmt::DependentScopeDeclRefExprClass:
1782 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1783 }
1784 }
1785};
1786class MemberRefVisit : public VisitorJob {
1787public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001788 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001789 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1790 L.getPtrEncoding()) {}
1791 static bool classof(const VisitorJob *VJ) {
1792 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1793 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001794 const FieldDecl *get() const {
1795 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001796 }
1797 SourceLocation getLoc() const {
1798 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1799 }
1800};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001801class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001802 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001803 VisitorWorkList &WL;
1804 CXCursor Parent;
1805public:
1806 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1807 : WL(wl), Parent(parent) {}
1808
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001809 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1810 void VisitBlockExpr(const BlockExpr *B);
1811 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1812 void VisitCompoundStmt(const CompoundStmt *S);
1813 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1814 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1815 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1816 void VisitCXXNewExpr(const CXXNewExpr *E);
1817 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1818 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1819 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1820 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1821 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1822 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1823 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1824 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1825 void VisitDeclRefExpr(const DeclRefExpr *D);
1826 void VisitDeclStmt(const DeclStmt *S);
1827 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1828 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1829 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1830 void VisitForStmt(const ForStmt *FS);
1831 void VisitGotoStmt(const GotoStmt *GS);
1832 void VisitIfStmt(const IfStmt *If);
1833 void VisitInitListExpr(const InitListExpr *IE);
1834 void VisitMemberExpr(const MemberExpr *M);
1835 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1836 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1837 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1838 void VisitOverloadExpr(const OverloadExpr *E);
1839 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1840 void VisitStmt(const Stmt *S);
1841 void VisitSwitchStmt(const SwitchStmt *S);
1842 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001843 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1844 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1845 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1846 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1847 void VisitVAArgExpr(const VAArgExpr *E);
1848 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1849 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1850 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1851 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001852 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1853 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001854 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001855
Guy Benyei11169dd2012-12-18 14:30:41 +00001856private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001857 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001858 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1859 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001860 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1861 void AddStmt(const Stmt *S);
1862 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001863 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001864 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001865 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001866};
1867} // end anonyous namespace
1868
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001869void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001870 // 'S' should always be non-null, since it comes from the
1871 // statement we are visiting.
1872 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1873}
1874
1875void
1876EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1877 if (Qualifier)
1878 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1879}
1880
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001881void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001882 if (S)
1883 WL.push_back(StmtVisit(S, Parent));
1884}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001885void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001886 if (D)
1887 WL.push_back(DeclVisit(D, Parent, isFirst));
1888}
1889void EnqueueVisitor::
1890 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1891 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001892 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001893}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001894void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001895 if (D)
1896 WL.push_back(MemberRefVisit(D, L, Parent));
1897}
1898void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1899 if (TI)
1900 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1901 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001903 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001904 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001905 AddStmt(*Child);
1906 }
1907 if (size == WL.size())
1908 return;
1909 // Now reverse the entries we just added. This will match the DFS
1910 // ordering performed by the worklist.
1911 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1912 std::reverse(I, E);
1913}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001914namespace {
1915class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1916 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001917 /// \brief Process clauses with list of variables.
1918 template <typename T>
1919 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001920public:
1921 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1922#define OPENMP_CLAUSE(Name, Class) \
1923 void Visit##Class(const Class *C);
1924#include "clang/Basic/OpenMPKinds.def"
1925};
1926
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001927void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1928 Visitor->AddStmt(C->getCondition());
1929}
1930
Alexey Bataev568a8332014-03-06 06:15:19 +00001931void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1932 Visitor->AddStmt(C->getNumThreads());
1933}
1934
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001935void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001936
1937template<typename T>
1938void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001939 for (const auto *I : Node->varlists())
1940 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001941}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001942
1943void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001944 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001945}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001946void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1947 const OMPFirstprivateClause *C) {
1948 VisitOMPClauseList(C);
1949}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001950void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001951 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001952}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001953}
Alexey Bataev756c1962013-09-24 03:17:45 +00001954
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001955void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1956 unsigned size = WL.size();
1957 OMPClauseEnqueue Visitor(this);
1958 Visitor.Visit(S);
1959 if (size == WL.size())
1960 return;
1961 // Now reverse the entries we just added. This will match the DFS
1962 // ordering performed by the worklist.
1963 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1964 std::reverse(I, E);
1965}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001966void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001967 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1968}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001969void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001970 AddDecl(B->getBlockDecl());
1971}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001972void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001973 EnqueueChildren(E);
1974 AddTypeLoc(E->getTypeSourceInfo());
1975}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001976void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1977 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001978 E = S->body_rend(); I != E; ++I) {
1979 AddStmt(*I);
1980 }
1981}
1982void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001983VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001984 AddStmt(S->getSubStmt());
1985 AddDeclarationNameInfo(S);
1986 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1987 AddNestedNameSpecifierLoc(QualifierLoc);
1988}
1989
1990void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001991VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001992 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1993 AddDeclarationNameInfo(E);
1994 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1995 AddNestedNameSpecifierLoc(QualifierLoc);
1996 if (!E->isImplicitAccess())
1997 AddStmt(E->getBase());
1998}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001999void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002000 // Enqueue the initializer , if any.
2001 AddStmt(E->getInitializer());
2002 // Enqueue the array size, if any.
2003 AddStmt(E->getArraySize());
2004 // Enqueue the allocated type.
2005 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2006 // Enqueue the placement arguments.
2007 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2008 AddStmt(E->getPlacementArg(I-1));
2009}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002010void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002011 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2012 AddStmt(CE->getArg(I-1));
2013 AddStmt(CE->getCallee());
2014 AddStmt(CE->getArg(0));
2015}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002016void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2017 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002018 // Visit the name of the type being destroyed.
2019 AddTypeLoc(E->getDestroyedTypeInfo());
2020 // Visit the scope type that looks disturbingly like the nested-name-specifier
2021 // but isn't.
2022 AddTypeLoc(E->getScopeTypeInfo());
2023 // Visit the nested-name-specifier.
2024 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2025 AddNestedNameSpecifierLoc(QualifierLoc);
2026 // Visit base expression.
2027 AddStmt(E->getBase());
2028}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002029void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2030 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002031 AddTypeLoc(E->getTypeSourceInfo());
2032}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002033void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2034 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002035 EnqueueChildren(E);
2036 AddTypeLoc(E->getTypeSourceInfo());
2037}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002038void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002039 EnqueueChildren(E);
2040 if (E->isTypeOperand())
2041 AddTypeLoc(E->getTypeOperandSourceInfo());
2042}
2043
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002044void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2045 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002046 EnqueueChildren(E);
2047 AddTypeLoc(E->getTypeSourceInfo());
2048}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002049void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002050 EnqueueChildren(E);
2051 if (E->isTypeOperand())
2052 AddTypeLoc(E->getTypeOperandSourceInfo());
2053}
2054
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002055void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002056 EnqueueChildren(S);
2057 AddDecl(S->getExceptionDecl());
2058}
2059
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002060void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002061 if (DR->hasExplicitTemplateArgs()) {
2062 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2063 }
2064 WL.push_back(DeclRefExprParts(DR, Parent));
2065}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002066void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2067 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002068 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2069 AddDeclarationNameInfo(E);
2070 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2071}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002072void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002073 unsigned size = WL.size();
2074 bool isFirst = true;
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002075 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00002076 D != DEnd; ++D) {
2077 AddDecl(*D, isFirst);
2078 isFirst = false;
2079 }
2080 if (size == WL.size())
2081 return;
2082 // Now reverse the entries we just added. This will match the DFS
2083 // ordering performed by the worklist.
2084 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2085 std::reverse(I, E);
2086}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002087void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002088 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002089 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002090 D = E->designators_rbegin(), DEnd = E->designators_rend();
2091 D != DEnd; ++D) {
2092 if (D->isFieldDesignator()) {
2093 if (FieldDecl *Field = D->getField())
2094 AddMemberRef(Field, D->getFieldLoc());
2095 continue;
2096 }
2097 if (D->isArrayDesignator()) {
2098 AddStmt(E->getArrayIndex(*D));
2099 continue;
2100 }
2101 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2102 AddStmt(E->getArrayRangeEnd(*D));
2103 AddStmt(E->getArrayRangeStart(*D));
2104 }
2105}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002106void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002107 EnqueueChildren(E);
2108 AddTypeLoc(E->getTypeInfoAsWritten());
2109}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002110void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002111 AddStmt(FS->getBody());
2112 AddStmt(FS->getInc());
2113 AddStmt(FS->getCond());
2114 AddDecl(FS->getConditionVariable());
2115 AddStmt(FS->getInit());
2116}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002117void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002118 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2119}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002120void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002121 AddStmt(If->getElse());
2122 AddStmt(If->getThen());
2123 AddStmt(If->getCond());
2124 AddDecl(If->getConditionVariable());
2125}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002126void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002127 // We care about the syntactic form of the initializer list, only.
2128 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2129 IE = Syntactic;
2130 EnqueueChildren(IE);
2131}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002132void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002133 WL.push_back(MemberExprParts(M, Parent));
2134
2135 // If the base of the member access expression is an implicit 'this', don't
2136 // visit it.
2137 // FIXME: If we ever want to show these implicit accesses, this will be
2138 // unfortunate. However, clang_getCursor() relies on this behavior.
2139 if (!M->isImplicitAccess())
2140 AddStmt(M->getBase());
2141}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002142void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002143 AddTypeLoc(E->getEncodedTypeSourceInfo());
2144}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002145void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002146 EnqueueChildren(M);
2147 AddTypeLoc(M->getClassReceiverTypeInfo());
2148}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002149void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002150 // Visit the components of the offsetof expression.
2151 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2152 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2153 const OffsetOfNode &Node = E->getComponent(I-1);
2154 switch (Node.getKind()) {
2155 case OffsetOfNode::Array:
2156 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2157 break;
2158 case OffsetOfNode::Field:
2159 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2160 break;
2161 case OffsetOfNode::Identifier:
2162 case OffsetOfNode::Base:
2163 continue;
2164 }
2165 }
2166 // Visit the type into which we're computing the offset.
2167 AddTypeLoc(E->getTypeSourceInfo());
2168}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002169void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002170 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2171 WL.push_back(OverloadExprParts(E, Parent));
2172}
2173void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002174 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002175 EnqueueChildren(E);
2176 if (E->isArgumentType())
2177 AddTypeLoc(E->getArgumentTypeInfo());
2178}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002179void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002180 EnqueueChildren(S);
2181}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002182void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002183 AddStmt(S->getBody());
2184 AddStmt(S->getCond());
2185 AddDecl(S->getConditionVariable());
2186}
2187
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002188void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002189 AddStmt(W->getBody());
2190 AddStmt(W->getCond());
2191 AddDecl(W->getConditionVariable());
2192}
2193
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002194void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002195 for (unsigned I = E->getNumArgs(); I > 0; --I)
2196 AddTypeLoc(E->getArg(I-1));
2197}
2198
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002199void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002200 AddTypeLoc(E->getQueriedTypeSourceInfo());
2201}
2202
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002203void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002204 EnqueueChildren(E);
2205}
2206
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002207void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002208 VisitOverloadExpr(U);
2209 if (!U->isImplicitAccess())
2210 AddStmt(U->getBase());
2211}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002212void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002213 AddStmt(E->getSubExpr());
2214 AddTypeLoc(E->getWrittenTypeInfo());
2215}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002216void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002217 WL.push_back(SizeOfPackExprParts(E, Parent));
2218}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002219void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002220 // If the opaque value has a source expression, just transparently
2221 // visit that. This is useful for (e.g.) pseudo-object expressions.
2222 if (Expr *SourceExpr = E->getSourceExpr())
2223 return Visit(SourceExpr);
2224}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002225void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002226 AddStmt(E->getBody());
2227 WL.push_back(LambdaExprParts(E, Parent));
2228}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002229void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002230 // Treat the expression like its syntactic form.
2231 Visit(E->getSyntacticForm());
2232}
2233
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002234void EnqueueVisitor::VisitOMPExecutableDirective(
2235 const OMPExecutableDirective *D) {
2236 EnqueueChildren(D);
2237 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2238 E = D->clauses().end();
2239 I != E; ++I)
2240 EnqueueChildren(*I);
2241}
2242
2243void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2244 VisitOMPExecutableDirective(D);
2245}
2246
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002247void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2248 VisitOMPExecutableDirective(D);
2249}
2250
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002251void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002252 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2253}
2254
2255bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2256 if (RegionOfInterest.isValid()) {
2257 SourceRange Range = getRawCursorExtent(C);
2258 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2259 return false;
2260 }
2261 return true;
2262}
2263
2264bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2265 while (!WL.empty()) {
2266 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002267 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002268
2269 // Set the Parent field, then back to its old value once we're done.
2270 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2271
2272 switch (LI.getKind()) {
2273 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002274 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002275 if (!D)
2276 continue;
2277
2278 // For now, perform default visitation for Decls.
2279 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2280 cast<DeclVisit>(&LI)->isFirst())))
2281 return true;
2282
2283 continue;
2284 }
2285 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2286 const ASTTemplateArgumentListInfo *ArgList =
2287 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2288 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2289 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2290 Arg != ArgEnd; ++Arg) {
2291 if (VisitTemplateArgumentLoc(*Arg))
2292 return true;
2293 }
2294 continue;
2295 }
2296 case VisitorJob::TypeLocVisitKind: {
2297 // Perform default visitation for TypeLocs.
2298 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2299 return true;
2300 continue;
2301 }
2302 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002303 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002304 if (LabelStmt *stmt = LS->getStmt()) {
2305 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2306 TU))) {
2307 return true;
2308 }
2309 }
2310 continue;
2311 }
2312
2313 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2314 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2315 if (VisitNestedNameSpecifierLoc(V->get()))
2316 return true;
2317 continue;
2318 }
2319
2320 case VisitorJob::DeclarationNameInfoVisitKind: {
2321 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2322 ->get()))
2323 return true;
2324 continue;
2325 }
2326 case VisitorJob::MemberRefVisitKind: {
2327 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2328 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2329 return true;
2330 continue;
2331 }
2332 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002333 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002334 if (!S)
2335 continue;
2336
2337 // Update the current cursor.
2338 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2339 if (!IsInRegionOfInterest(Cursor))
2340 continue;
2341 switch (Visitor(Cursor, Parent, ClientData)) {
2342 case CXChildVisit_Break: return true;
2343 case CXChildVisit_Continue: break;
2344 case CXChildVisit_Recurse:
2345 if (PostChildrenVisitor)
2346 WL.push_back(PostChildrenVisit(0, Cursor));
2347 EnqueueWorkList(WL, S);
2348 break;
2349 }
2350 continue;
2351 }
2352 case VisitorJob::MemberExprPartsKind: {
2353 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002354 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002355
2356 // Visit the nested-name-specifier
2357 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2358 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2359 return true;
2360
2361 // Visit the declaration name.
2362 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2363 return true;
2364
2365 // Visit the explicitly-specified template arguments, if any.
2366 if (M->hasExplicitTemplateArgs()) {
2367 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2368 *ArgEnd = Arg + M->getNumTemplateArgs();
2369 Arg != ArgEnd; ++Arg) {
2370 if (VisitTemplateArgumentLoc(*Arg))
2371 return true;
2372 }
2373 }
2374 continue;
2375 }
2376 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002377 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002378 // Visit nested-name-specifier, if present.
2379 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2380 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2381 return true;
2382 // Visit declaration name.
2383 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2384 return true;
2385 continue;
2386 }
2387 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002388 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002389 // Visit the nested-name-specifier.
2390 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2391 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2392 return true;
2393 // Visit the declaration name.
2394 if (VisitDeclarationNameInfo(O->getNameInfo()))
2395 return true;
2396 // Visit the overloaded declaration reference.
2397 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2398 return true;
2399 continue;
2400 }
2401 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002402 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002403 NamedDecl *Pack = E->getPack();
2404 if (isa<TemplateTypeParmDecl>(Pack)) {
2405 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2406 E->getPackLoc(), TU)))
2407 return true;
2408
2409 continue;
2410 }
2411
2412 if (isa<TemplateTemplateParmDecl>(Pack)) {
2413 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2414 E->getPackLoc(), TU)))
2415 return true;
2416
2417 continue;
2418 }
2419
2420 // Non-type template parameter packs and function parameter packs are
2421 // treated like DeclRefExpr cursors.
2422 continue;
2423 }
2424
2425 case VisitorJob::LambdaExprPartsKind: {
2426 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002427 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002428 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2429 CEnd = E->explicit_capture_end();
2430 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002431 // FIXME: Lambda init-captures.
2432 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002433 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002434
Guy Benyei11169dd2012-12-18 14:30:41 +00002435 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2436 C->getLocation(),
2437 TU)))
2438 return true;
2439 }
2440
2441 // Visit parameters and return type, if present.
2442 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2443 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2444 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2445 // Visit the whole type.
2446 if (Visit(TL))
2447 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002448 } else if (FunctionProtoTypeLoc Proto =
2449 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002450 if (E->hasExplicitParameters()) {
2451 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002452 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2453 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002454 return true;
2455 } else {
2456 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002457 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002458 return true;
2459 }
2460 }
2461 }
2462 break;
2463 }
2464
2465 case VisitorJob::PostChildrenVisitKind:
2466 if (PostChildrenVisitor(Parent, ClientData))
2467 return true;
2468 break;
2469 }
2470 }
2471 return false;
2472}
2473
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002474bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002475 VisitorWorkList *WL = 0;
2476 if (!WorkListFreeList.empty()) {
2477 WL = WorkListFreeList.back();
2478 WL->clear();
2479 WorkListFreeList.pop_back();
2480 }
2481 else {
2482 WL = new VisitorWorkList();
2483 WorkListCache.push_back(WL);
2484 }
2485 EnqueueWorkList(*WL, S);
2486 bool result = RunVisitorWorkList(*WL);
2487 WorkListFreeList.push_back(WL);
2488 return result;
2489}
2490
2491namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002492typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002493RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2494 const DeclarationNameInfo &NI,
2495 const SourceRange &QLoc,
2496 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2497 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2498 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2499 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2500
2501 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2502
2503 RefNamePieces Pieces;
2504
2505 if (WantQualifier && QLoc.isValid())
2506 Pieces.push_back(QLoc);
2507
2508 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2509 Pieces.push_back(NI.getLoc());
2510
2511 if (WantTemplateArgs && TemplateArgs)
2512 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2513 TemplateArgs->RAngleLoc));
2514
2515 if (Kind == DeclarationName::CXXOperatorName) {
2516 Pieces.push_back(SourceLocation::getFromRawEncoding(
2517 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2518 Pieces.push_back(SourceLocation::getFromRawEncoding(
2519 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2520 }
2521
2522 if (WantSinglePiece) {
2523 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2524 Pieces.clear();
2525 Pieces.push_back(R);
2526 }
2527
2528 return Pieces;
2529}
2530}
2531
2532//===----------------------------------------------------------------------===//
2533// Misc. API hooks.
2534//===----------------------------------------------------------------------===//
2535
2536static llvm::sys::Mutex EnableMultithreadingMutex;
2537static bool EnabledMultithreading;
2538
Chad Rosier05c71aa2013-03-27 18:28:23 +00002539static void fatal_error_handler(void *user_data, const std::string& reason,
2540 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002541 // Write the result out to stderr avoiding errs() because raw_ostreams can
2542 // call report_fatal_error.
2543 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2544 ::abort();
2545}
2546
2547extern "C" {
2548CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2549 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002550 // We use crash recovery to make some of our APIs more reliable, implicitly
2551 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002552 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2553 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002554
2555 // Enable support for multithreading in LLVM.
2556 {
2557 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2558 if (!EnabledMultithreading) {
2559 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2560 llvm::llvm_start_multithreaded();
2561 EnabledMultithreading = true;
2562 }
2563 }
2564
2565 CIndexer *CIdxr = new CIndexer();
2566 if (excludeDeclarationsFromPCH)
2567 CIdxr->setOnlyLocalDecls();
2568 if (displayDiagnostics)
2569 CIdxr->setDisplayDiagnostics();
2570
2571 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2572 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2573 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2574 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2575 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2576 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2577
2578 return CIdxr;
2579}
2580
2581void clang_disposeIndex(CXIndex CIdx) {
2582 if (CIdx)
2583 delete static_cast<CIndexer *>(CIdx);
2584}
2585
2586void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2587 if (CIdx)
2588 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2589}
2590
2591unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2592 if (CIdx)
2593 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2594 return 0;
2595}
2596
2597void clang_toggleCrashRecovery(unsigned isEnabled) {
2598 if (isEnabled)
2599 llvm::CrashRecoveryContext::Enable();
2600 else
2601 llvm::CrashRecoveryContext::Disable();
2602}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002603
Guy Benyei11169dd2012-12-18 14:30:41 +00002604CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2605 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002606 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002607 enum CXErrorCode Result =
2608 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002609 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002610 assert((TU && Result == CXError_Success) ||
2611 (!TU && Result != CXError_Success));
2612 return TU;
2613}
2614
2615enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2616 const char *ast_filename,
2617 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002618 if (out_TU)
2619 *out_TU = NULL;
2620
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002621 if (!CIdx || !ast_filename || !out_TU)
2622 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002623
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002624 LOG_FUNC_SECTION {
2625 *Log << ast_filename;
2626 }
2627
Guy Benyei11169dd2012-12-18 14:30:41 +00002628 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2629 FileSystemOptions FileSystemOpts;
2630
2631 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002632 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002633 CXXIdx->getOnlyLocalDecls(), None,
2634 /*CaptureDiagnostics=*/true,
2635 /*AllowPCHWithCompilerErrors=*/true,
2636 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002637 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2638 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002639}
2640
2641unsigned clang_defaultEditingTranslationUnitOptions() {
2642 return CXTranslationUnit_PrecompiledPreamble |
2643 CXTranslationUnit_CacheCompletionResults;
2644}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002645
Guy Benyei11169dd2012-12-18 14:30:41 +00002646CXTranslationUnit
2647clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2648 const char *source_filename,
2649 int num_command_line_args,
2650 const char * const *command_line_args,
2651 unsigned num_unsaved_files,
2652 struct CXUnsavedFile *unsaved_files) {
2653 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2654 return clang_parseTranslationUnit(CIdx, source_filename,
2655 command_line_args, num_command_line_args,
2656 unsaved_files, num_unsaved_files,
2657 Options);
2658}
2659
2660struct ParseTranslationUnitInfo {
2661 CXIndex CIdx;
2662 const char *source_filename;
2663 const char *const *command_line_args;
2664 int num_command_line_args;
2665 struct CXUnsavedFile *unsaved_files;
2666 unsigned num_unsaved_files;
2667 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002668 CXTranslationUnit *out_TU;
2669 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002670};
2671static void clang_parseTranslationUnit_Impl(void *UserData) {
2672 ParseTranslationUnitInfo *PTUI =
2673 static_cast<ParseTranslationUnitInfo*>(UserData);
2674 CXIndex CIdx = PTUI->CIdx;
2675 const char *source_filename = PTUI->source_filename;
2676 const char * const *command_line_args = PTUI->command_line_args;
2677 int num_command_line_args = PTUI->num_command_line_args;
2678 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2679 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2680 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002681 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002682
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002683 // Set up the initial return values.
2684 if (out_TU)
2685 *out_TU = NULL;
2686 PTUI->result = CXError_Failure;
2687
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002688 // Check arguments.
2689 if (!CIdx || !out_TU ||
2690 (unsaved_files == NULL && num_unsaved_files != 0)) {
2691 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002692 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002693 }
2694
Guy Benyei11169dd2012-12-18 14:30:41 +00002695 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2696
2697 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2698 setThreadBackgroundPriority();
2699
2700 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2701 // FIXME: Add a flag for modules.
2702 TranslationUnitKind TUKind
2703 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002704 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002705 = options & CXTranslationUnit_CacheCompletionResults;
2706 bool IncludeBriefCommentsInCodeCompletion
2707 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2708 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2709 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2710
2711 // Configure the diagnostics.
2712 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002713 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002714
2715 // Recover resources if we crash before exiting this function.
2716 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2717 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2718 DiagCleanup(Diags.getPtr());
2719
Ahmed Charlesb8984322014-03-07 20:03:18 +00002720 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2721 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002722
2723 // Recover resources if we crash before exiting this function.
2724 llvm::CrashRecoveryContextCleanupRegistrar<
2725 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2726
2727 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2728 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2729 const llvm::MemoryBuffer *Buffer
2730 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2731 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2732 Buffer));
2733 }
2734
Ahmed Charlesb8984322014-03-07 20:03:18 +00002735 std::unique_ptr<std::vector<const char *>> Args(
2736 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002737
2738 // Recover resources if we crash before exiting this method.
2739 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2740 ArgsCleanup(Args.get());
2741
2742 // Since the Clang C library is primarily used by batch tools dealing with
2743 // (often very broken) source code, where spell-checking can have a
2744 // significant negative impact on performance (particularly when
2745 // precompiled headers are involved), we disable it by default.
2746 // Only do this if we haven't found a spell-checking-related argument.
2747 bool FoundSpellCheckingArgument = false;
2748 for (int I = 0; I != num_command_line_args; ++I) {
2749 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2750 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2751 FoundSpellCheckingArgument = true;
2752 break;
2753 }
2754 }
2755 if (!FoundSpellCheckingArgument)
2756 Args->push_back("-fno-spell-checking");
2757
2758 Args->insert(Args->end(), command_line_args,
2759 command_line_args + num_command_line_args);
2760
2761 // The 'source_filename' argument is optional. If the caller does not
2762 // specify it then it is assumed that the source file is specified
2763 // in the actual argument list.
2764 // Put the source file after command_line_args otherwise if '-x' flag is
2765 // present it will be unused.
2766 if (source_filename)
2767 Args->push_back(source_filename);
2768
2769 // Do we need the detailed preprocessing record?
2770 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2771 Args->push_back("-Xclang");
2772 Args->push_back("-detailed-preprocessing-record");
2773 }
2774
2775 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002776 std::unique_ptr<ASTUnit> ErrUnit;
2777 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002778 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002779 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2780 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2781 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2782 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2783 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2784 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002785
2786 if (NumErrors != Diags->getClient()->getNumErrors()) {
2787 // Make sure to check that 'Unit' is non-NULL.
2788 if (CXXIdx->getDisplayDiagnostics())
2789 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2790 }
2791
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002792 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2793 PTUI->result = CXError_ASTReadError;
2794 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002795 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002796 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2797 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002798}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002799
2800CXTranslationUnit
2801clang_parseTranslationUnit(CXIndex CIdx,
2802 const char *source_filename,
2803 const char *const *command_line_args,
2804 int num_command_line_args,
2805 struct CXUnsavedFile *unsaved_files,
2806 unsigned num_unsaved_files,
2807 unsigned options) {
2808 CXTranslationUnit TU;
2809 enum CXErrorCode Result = clang_parseTranslationUnit2(
2810 CIdx, source_filename, command_line_args, num_command_line_args,
2811 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002812 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002813 assert((TU && Result == CXError_Success) ||
2814 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002815 return TU;
2816}
2817
2818enum CXErrorCode clang_parseTranslationUnit2(
2819 CXIndex CIdx,
2820 const char *source_filename,
2821 const char *const *command_line_args,
2822 int num_command_line_args,
2823 struct CXUnsavedFile *unsaved_files,
2824 unsigned num_unsaved_files,
2825 unsigned options,
2826 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002827 LOG_FUNC_SECTION {
2828 *Log << source_filename << ": ";
2829 for (int i = 0; i != num_command_line_args; ++i)
2830 *Log << command_line_args[i] << " ";
2831 }
2832
Guy Benyei11169dd2012-12-18 14:30:41 +00002833 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2834 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002835 num_unsaved_files, options, out_TU,
2836 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002837 llvm::CrashRecoveryContext CRC;
2838
2839 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2840 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2841 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2842 fprintf(stderr, " 'command_line_args' : [");
2843 for (int i = 0; i != num_command_line_args; ++i) {
2844 if (i)
2845 fprintf(stderr, ", ");
2846 fprintf(stderr, "'%s'", command_line_args[i]);
2847 }
2848 fprintf(stderr, "],\n");
2849 fprintf(stderr, " 'unsaved_files' : [");
2850 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2851 if (i)
2852 fprintf(stderr, ", ");
2853 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2854 unsaved_files[i].Length);
2855 }
2856 fprintf(stderr, "],\n");
2857 fprintf(stderr, " 'options' : %d,\n", options);
2858 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002859
2860 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002861 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002862 if (CXTranslationUnit *TU = PTUI.out_TU)
2863 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002864 }
2865
2866 return PTUI.result;
2867}
2868
2869unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2870 return CXSaveTranslationUnit_None;
2871}
2872
2873namespace {
2874
2875struct SaveTranslationUnitInfo {
2876 CXTranslationUnit TU;
2877 const char *FileName;
2878 unsigned options;
2879 CXSaveError result;
2880};
2881
2882}
2883
2884static void clang_saveTranslationUnit_Impl(void *UserData) {
2885 SaveTranslationUnitInfo *STUI =
2886 static_cast<SaveTranslationUnitInfo*>(UserData);
2887
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002888 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002889 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2890 setThreadBackgroundPriority();
2891
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002892 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002893 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2894}
2895
2896int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2897 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002898 LOG_FUNC_SECTION {
2899 *Log << TU << ' ' << FileName;
2900 }
2901
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002902 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002903 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002904 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002905 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002906
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002907 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002908 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2909 if (!CXXUnit->hasSema())
2910 return CXSaveError_InvalidTU;
2911
2912 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2913
2914 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2915 getenv("LIBCLANG_NOTHREADS")) {
2916 clang_saveTranslationUnit_Impl(&STUI);
2917
2918 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2919 PrintLibclangResourceUsage(TU);
2920
2921 return STUI.result;
2922 }
2923
2924 // We have an AST that has invalid nodes due to compiler errors.
2925 // Use a crash recovery thread for protection.
2926
2927 llvm::CrashRecoveryContext CRC;
2928
2929 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2930 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2931 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2932 fprintf(stderr, " 'options' : %d,\n", options);
2933 fprintf(stderr, "}\n");
2934
2935 return CXSaveError_Unknown;
2936
2937 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2938 PrintLibclangResourceUsage(TU);
2939 }
2940
2941 return STUI.result;
2942}
2943
2944void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2945 if (CTUnit) {
2946 // If the translation unit has been marked as unsafe to free, just discard
2947 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002948 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2949 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002950 return;
2951
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002952 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002953 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002954 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2955 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002956 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002957 delete CTUnit;
2958 }
2959}
2960
2961unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2962 return CXReparse_None;
2963}
2964
2965struct ReparseTranslationUnitInfo {
2966 CXTranslationUnit TU;
2967 unsigned num_unsaved_files;
2968 struct CXUnsavedFile *unsaved_files;
2969 unsigned options;
2970 int result;
2971};
2972
2973static void clang_reparseTranslationUnit_Impl(void *UserData) {
2974 ReparseTranslationUnitInfo *RTUI =
2975 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002976 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002977
Guy Benyei11169dd2012-12-18 14:30:41 +00002978 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002979 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2980 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2981 unsigned options = RTUI->options;
2982 (void) options;
2983
2984 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002985 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002986 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002987 RTUI->result = CXError_InvalidArguments;
2988 return;
2989 }
2990 if (unsaved_files == NULL && num_unsaved_files != 0) {
2991 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00002992 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002993 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002994
2995 // Reset the associated diagnostics.
2996 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2997 TU->Diagnostics = 0;
2998
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002999 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003000 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3001 setThreadBackgroundPriority();
3002
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003003 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003004 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003005
3006 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3007 new std::vector<ASTUnit::RemappedFile>());
3008
Guy Benyei11169dd2012-12-18 14:30:41 +00003009 // Recover resources if we crash before exiting this function.
3010 llvm::CrashRecoveryContextCleanupRegistrar<
3011 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3012
3013 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3014 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3015 const llvm::MemoryBuffer *Buffer
3016 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3017 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3018 Buffer));
3019 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003020
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003021 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003022 RTUI->result = CXError_Success;
3023 else if (isASTReadError(CXXUnit))
3024 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003025}
3026
3027int clang_reparseTranslationUnit(CXTranslationUnit TU,
3028 unsigned num_unsaved_files,
3029 struct CXUnsavedFile *unsaved_files,
3030 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003031 LOG_FUNC_SECTION {
3032 *Log << TU;
3033 }
3034
Guy Benyei11169dd2012-12-18 14:30:41 +00003035 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003036 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003037
3038 if (getenv("LIBCLANG_NOTHREADS")) {
3039 clang_reparseTranslationUnit_Impl(&RTUI);
3040 return RTUI.result;
3041 }
3042
3043 llvm::CrashRecoveryContext CRC;
3044
3045 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3046 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003047 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003048 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003049 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3050 PrintLibclangResourceUsage(TU);
3051
3052 return RTUI.result;
3053}
3054
3055
3056CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003057 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003058 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003059 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003060 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003061
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003062 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003063 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003064}
3065
3066CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003067 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003068 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003069 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003070 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003071
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003072 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003073 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3074}
3075
3076} // end: extern "C"
3077
3078//===----------------------------------------------------------------------===//
3079// CXFile Operations.
3080//===----------------------------------------------------------------------===//
3081
3082extern "C" {
3083CXString clang_getFileName(CXFile SFile) {
3084 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003085 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003086
3087 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003088 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003089}
3090
3091time_t clang_getFileTime(CXFile SFile) {
3092 if (!SFile)
3093 return 0;
3094
3095 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3096 return FEnt->getModificationTime();
3097}
3098
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003099CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003100 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003101 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003102 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003103 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003104
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003105 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003106
3107 FileManager &FMgr = CXXUnit->getFileManager();
3108 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3109}
3110
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003111unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3112 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003113 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003114 LOG_BAD_TU(TU);
3115 return 0;
3116 }
3117
3118 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003119 return 0;
3120
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003121 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003122 FileEntry *FEnt = static_cast<FileEntry *>(file);
3123 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3124 .isFileMultipleIncludeGuarded(FEnt);
3125}
3126
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003127int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3128 if (!file || !outID)
3129 return 1;
3130
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003131 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003132 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3133 outID->data[0] = ID.getDevice();
3134 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003135 outID->data[2] = FEnt->getModificationTime();
3136 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003137}
3138
Guy Benyei11169dd2012-12-18 14:30:41 +00003139} // end: extern "C"
3140
3141//===----------------------------------------------------------------------===//
3142// CXCursor Operations.
3143//===----------------------------------------------------------------------===//
3144
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003145static const Decl *getDeclFromExpr(const Stmt *E) {
3146 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003147 return getDeclFromExpr(CE->getSubExpr());
3148
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003149 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003150 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003151 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003152 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003153 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003154 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003155 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003156 if (PRE->isExplicitProperty())
3157 return PRE->getExplicitProperty();
3158 // It could be messaging both getter and setter as in:
3159 // ++myobj.myprop;
3160 // in which case prefer to associate the setter since it is less obvious
3161 // from inspecting the source that the setter is going to get called.
3162 if (PRE->isMessagingSetter())
3163 return PRE->getImplicitPropertySetter();
3164 return PRE->getImplicitPropertyGetter();
3165 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003166 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003167 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003168 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003169 if (Expr *Src = OVE->getSourceExpr())
3170 return getDeclFromExpr(Src);
3171
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003172 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003173 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003174 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003175 if (!CE->isElidable())
3176 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003177 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003178 return OME->getMethodDecl();
3179
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003180 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003181 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003182 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003183 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3184 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003185 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003186 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3187 isa<ParmVarDecl>(SizeOfPack->getPack()))
3188 return SizeOfPack->getPack();
3189
3190 return 0;
3191}
3192
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003193static SourceLocation getLocationFromExpr(const Expr *E) {
3194 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003195 return getLocationFromExpr(CE->getSubExpr());
3196
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003197 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003198 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003199 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003200 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003201 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003202 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003203 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003204 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003205 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003206 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003207 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003208 return PropRef->getLocation();
3209
3210 return E->getLocStart();
3211}
3212
3213extern "C" {
3214
3215unsigned clang_visitChildren(CXCursor parent,
3216 CXCursorVisitor visitor,
3217 CXClientData client_data) {
3218 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3219 /*VisitPreprocessorLast=*/false);
3220 return CursorVis.VisitChildren(parent);
3221}
3222
3223#ifndef __has_feature
3224#define __has_feature(x) 0
3225#endif
3226#if __has_feature(blocks)
3227typedef enum CXChildVisitResult
3228 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3229
3230static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3231 CXClientData client_data) {
3232 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3233 return block(cursor, parent);
3234}
3235#else
3236// If we are compiled with a compiler that doesn't have native blocks support,
3237// define and call the block manually, so the
3238typedef struct _CXChildVisitResult
3239{
3240 void *isa;
3241 int flags;
3242 int reserved;
3243 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3244 CXCursor);
3245} *CXCursorVisitorBlock;
3246
3247static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3248 CXClientData client_data) {
3249 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3250 return block->invoke(block, cursor, parent);
3251}
3252#endif
3253
3254
3255unsigned clang_visitChildrenWithBlock(CXCursor parent,
3256 CXCursorVisitorBlock block) {
3257 return clang_visitChildren(parent, visitWithBlock, block);
3258}
3259
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003260static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003261 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003262 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003263
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003264 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003265 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003266 if (const ObjCPropertyImplDecl *PropImpl =
3267 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003268 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003269 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003270
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003271 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003272 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003273 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003274
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003275 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003276 }
3277
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003278 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003279 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003280
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003281 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003282 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3283 // and returns different names. NamedDecl returns the class name and
3284 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003285 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003286
3287 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003288 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003289
3290 SmallString<1024> S;
3291 llvm::raw_svector_ostream os(S);
3292 ND->printName(os);
3293
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003294 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003295}
3296
3297CXString clang_getCursorSpelling(CXCursor C) {
3298 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003299 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003300
3301 if (clang_isReference(C.kind)) {
3302 switch (C.kind) {
3303 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003304 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003305 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003306 }
3307 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003308 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003309 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003310 }
3311 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003312 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003313 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003314 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003315 }
3316 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003317 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003318 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003319 }
3320 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003321 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003322 assert(Type && "Missing type decl");
3323
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003324 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003325 getAsString());
3326 }
3327 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003328 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003329 assert(Template && "Missing template decl");
3330
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003331 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003332 }
3333
3334 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003335 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003336 assert(NS && "Missing namespace decl");
3337
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003338 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003339 }
3340
3341 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003342 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003343 assert(Field && "Missing member decl");
3344
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003345 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003346 }
3347
3348 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003349 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003350 assert(Label && "Missing label");
3351
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003352 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003353 }
3354
3355 case CXCursor_OverloadedDeclRef: {
3356 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003357 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3358 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003359 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003360 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003361 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003362 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003363 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003364 OverloadedTemplateStorage *Ovl
3365 = Storage.get<OverloadedTemplateStorage*>();
3366 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003367 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003368 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003369 }
3370
3371 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003372 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 assert(Var && "Missing variable decl");
3374
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003375 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003376 }
3377
3378 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003379 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 }
3381 }
3382
3383 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003384 const Expr *E = getCursorExpr(C);
3385
3386 if (C.kind == CXCursor_ObjCStringLiteral ||
3387 C.kind == CXCursor_StringLiteral) {
3388 const StringLiteral *SLit;
3389 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3390 SLit = OSL->getString();
3391 } else {
3392 SLit = cast<StringLiteral>(E);
3393 }
3394 SmallString<256> Buf;
3395 llvm::raw_svector_ostream OS(Buf);
3396 SLit->outputString(OS);
3397 return cxstring::createDup(OS.str());
3398 }
3399
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003400 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003401 if (D)
3402 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003403 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003404 }
3405
3406 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003407 const Stmt *S = getCursorStmt(C);
3408 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003409 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003410
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003411 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003412 }
3413
3414 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003415 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003416 ->getNameStart());
3417
3418 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003419 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003420 ->getNameStart());
3421
3422 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003423 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003424
3425 if (clang_isDeclaration(C.kind))
3426 return getDeclSpelling(getCursorDecl(C));
3427
3428 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003429 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003430 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003431 }
3432
3433 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003434 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003435 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003436 }
3437
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003438 if (C.kind == CXCursor_PackedAttr) {
3439 return cxstring::createRef("packed");
3440 }
3441
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003442 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003443}
3444
3445CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3446 unsigned pieceIndex,
3447 unsigned options) {
3448 if (clang_Cursor_isNull(C))
3449 return clang_getNullRange();
3450
3451 ASTContext &Ctx = getCursorContext(C);
3452
3453 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003454 const Stmt *S = getCursorStmt(C);
3455 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003456 if (pieceIndex > 0)
3457 return clang_getNullRange();
3458 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3459 }
3460
3461 return clang_getNullRange();
3462 }
3463
3464 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003465 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003466 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3467 if (pieceIndex >= ME->getNumSelectorLocs())
3468 return clang_getNullRange();
3469 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3470 }
3471 }
3472
3473 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3474 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003475 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003476 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3477 if (pieceIndex >= MD->getNumSelectorLocs())
3478 return clang_getNullRange();
3479 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3480 }
3481 }
3482
3483 if (C.kind == CXCursor_ObjCCategoryDecl ||
3484 C.kind == CXCursor_ObjCCategoryImplDecl) {
3485 if (pieceIndex > 0)
3486 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003487 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003488 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3489 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003490 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003491 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3492 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3493 }
3494
3495 if (C.kind == CXCursor_ModuleImportDecl) {
3496 if (pieceIndex > 0)
3497 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003498 if (const ImportDecl *ImportD =
3499 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003500 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3501 if (!Locs.empty())
3502 return cxloc::translateSourceRange(Ctx,
3503 SourceRange(Locs.front(), Locs.back()));
3504 }
3505 return clang_getNullRange();
3506 }
3507
3508 // FIXME: A CXCursor_InclusionDirective should give the location of the
3509 // filename, but we don't keep track of this.
3510
3511 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3512 // but we don't keep track of this.
3513
3514 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3515 // but we don't keep track of this.
3516
3517 // Default handling, give the location of the cursor.
3518
3519 if (pieceIndex > 0)
3520 return clang_getNullRange();
3521
3522 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3523 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3524 return cxloc::translateSourceRange(Ctx, Loc);
3525}
3526
3527CXString clang_getCursorDisplayName(CXCursor C) {
3528 if (!clang_isDeclaration(C.kind))
3529 return clang_getCursorSpelling(C);
3530
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003531 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003532 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003533 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003534
3535 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003536 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003537 D = FunTmpl->getTemplatedDecl();
3538
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003539 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003540 SmallString<64> Str;
3541 llvm::raw_svector_ostream OS(Str);
3542 OS << *Function;
3543 if (Function->getPrimaryTemplate())
3544 OS << "<>";
3545 OS << "(";
3546 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3547 if (I)
3548 OS << ", ";
3549 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3550 }
3551
3552 if (Function->isVariadic()) {
3553 if (Function->getNumParams())
3554 OS << ", ";
3555 OS << "...";
3556 }
3557 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003558 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003559 }
3560
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003561 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003562 SmallString<64> Str;
3563 llvm::raw_svector_ostream OS(Str);
3564 OS << *ClassTemplate;
3565 OS << "<";
3566 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3567 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3568 if (I)
3569 OS << ", ";
3570
3571 NamedDecl *Param = Params->getParam(I);
3572 if (Param->getIdentifier()) {
3573 OS << Param->getIdentifier()->getName();
3574 continue;
3575 }
3576
3577 // There is no parameter name, which makes this tricky. Try to come up
3578 // with something useful that isn't too long.
3579 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3580 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3581 else if (NonTypeTemplateParmDecl *NTTP
3582 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3583 OS << NTTP->getType().getAsString(Policy);
3584 else
3585 OS << "template<...> class";
3586 }
3587
3588 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003589 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003590 }
3591
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003592 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003593 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3594 // If the type was explicitly written, use that.
3595 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003596 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003597
Benjamin Kramer9170e912013-02-22 15:46:01 +00003598 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 llvm::raw_svector_ostream OS(Str);
3600 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003601 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003602 ClassSpec->getTemplateArgs().data(),
3603 ClassSpec->getTemplateArgs().size(),
3604 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003605 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003606 }
3607
3608 return clang_getCursorSpelling(C);
3609}
3610
3611CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3612 switch (Kind) {
3613 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003614 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003615 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003616 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003617 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003618 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003619 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003620 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003621 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003622 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003624 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003626 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003628 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003630 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003632 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003633 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003634 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003636 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003638 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003639 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003640 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003642 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003643 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003644 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003646 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003648 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003650 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003652 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003654 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003656 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003658 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003660 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003662 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003664 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003666 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003668 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003670 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003672 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003741 case CXCursor_ObjCSelfExpr:
3742 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003859 case CXCursor_PackedAttr:
3860 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003909 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003910 return cxstring::createRef("OMPParallelDirective");
3911 case CXCursor_OMPSimdDirective:
3912 return cxstring::createRef("OMPSimdDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 }
3914
3915 llvm_unreachable("Unhandled CXCursorKind");
3916}
3917
3918struct GetCursorData {
3919 SourceLocation TokenBeginLoc;
3920 bool PointsAtMacroArgExpansion;
3921 bool VisitedObjCPropertyImplDecl;
3922 SourceLocation VisitedDeclaratorDeclStartLoc;
3923 CXCursor &BestCursor;
3924
3925 GetCursorData(SourceManager &SM,
3926 SourceLocation tokenBegin, CXCursor &outputCursor)
3927 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3928 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3929 VisitedObjCPropertyImplDecl = false;
3930 }
3931};
3932
3933static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3934 CXCursor parent,
3935 CXClientData client_data) {
3936 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3937 CXCursor *BestCursor = &Data->BestCursor;
3938
3939 // If we point inside a macro argument we should provide info of what the
3940 // token is so use the actual cursor, don't replace it with a macro expansion
3941 // cursor.
3942 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3943 return CXChildVisit_Recurse;
3944
3945 if (clang_isDeclaration(cursor.kind)) {
3946 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003947 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003948 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3949 if (MD->isImplicit())
3950 return CXChildVisit_Break;
3951
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003952 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3954 // Check that when we have multiple @class references in the same line,
3955 // that later ones do not override the previous ones.
3956 // If we have:
3957 // @class Foo, Bar;
3958 // source ranges for both start at '@', so 'Bar' will end up overriding
3959 // 'Foo' even though the cursor location was at 'Foo'.
3960 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3961 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003962 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3964 if (PrevID != ID &&
3965 !PrevID->isThisDeclarationADefinition() &&
3966 !ID->isThisDeclarationADefinition())
3967 return CXChildVisit_Break;
3968 }
3969
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003970 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3972 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3973 // Check that when we have multiple declarators in the same line,
3974 // that later ones do not override the previous ones.
3975 // If we have:
3976 // int Foo, Bar;
3977 // source ranges for both start at 'int', so 'Bar' will end up overriding
3978 // 'Foo' even though the cursor location was at 'Foo'.
3979 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3980 return CXChildVisit_Break;
3981 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3982
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003983 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3985 (void)PropImp;
3986 // Check that when we have multiple @synthesize in the same line,
3987 // that later ones do not override the previous ones.
3988 // If we have:
3989 // @synthesize Foo, Bar;
3990 // source ranges for both start at '@', so 'Bar' will end up overriding
3991 // 'Foo' even though the cursor location was at 'Foo'.
3992 if (Data->VisitedObjCPropertyImplDecl)
3993 return CXChildVisit_Break;
3994 Data->VisitedObjCPropertyImplDecl = true;
3995 }
3996 }
3997
3998 if (clang_isExpression(cursor.kind) &&
3999 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004000 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 // Avoid having the cursor of an expression replace the declaration cursor
4002 // when the expression source range overlaps the declaration range.
4003 // This can happen for C++ constructor expressions whose range generally
4004 // include the variable declaration, e.g.:
4005 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4006 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4007 D->getLocation() == Data->TokenBeginLoc)
4008 return CXChildVisit_Break;
4009 }
4010 }
4011
4012 // If our current best cursor is the construction of a temporary object,
4013 // don't replace that cursor with a type reference, because we want
4014 // clang_getCursor() to point at the constructor.
4015 if (clang_isExpression(BestCursor->kind) &&
4016 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4017 cursor.kind == CXCursor_TypeRef) {
4018 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4019 // as having the actual point on the type reference.
4020 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4021 return CXChildVisit_Recurse;
4022 }
4023
4024 *BestCursor = cursor;
4025 return CXChildVisit_Recurse;
4026}
4027
4028CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004029 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004030 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004031 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004032 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004033
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004034 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4036
4037 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4038 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4039
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004040 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 CXFile SearchFile;
4042 unsigned SearchLine, SearchColumn;
4043 CXFile ResultFile;
4044 unsigned ResultLine, ResultColumn;
4045 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4046 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4047 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4048
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004049 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4050 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 &ResultColumn, 0);
4052 SearchFileName = clang_getFileName(SearchFile);
4053 ResultFileName = clang_getFileName(ResultFile);
4054 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4055 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004056 *Log << llvm::format("(%s:%d:%d) = %s",
4057 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4058 clang_getCString(KindSpelling))
4059 << llvm::format("(%s:%d:%d):%s%s",
4060 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4061 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 clang_disposeString(SearchFileName);
4063 clang_disposeString(ResultFileName);
4064 clang_disposeString(KindSpelling);
4065 clang_disposeString(USR);
4066
4067 CXCursor Definition = clang_getCursorDefinition(Result);
4068 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4069 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4070 CXString DefinitionKindSpelling
4071 = clang_getCursorKindSpelling(Definition.kind);
4072 CXFile DefinitionFile;
4073 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004074 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004075 &DefinitionLine, &DefinitionColumn, 0);
4076 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004077 *Log << llvm::format(" -> %s(%s:%d:%d)",
4078 clang_getCString(DefinitionKindSpelling),
4079 clang_getCString(DefinitionFileName),
4080 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 clang_disposeString(DefinitionFileName);
4082 clang_disposeString(DefinitionKindSpelling);
4083 }
4084 }
4085
4086 return Result;
4087}
4088
4089CXCursor clang_getNullCursor(void) {
4090 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4091}
4092
4093unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004094 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4095 // can't set consistently. For example, when visiting a DeclStmt we will set
4096 // it but we don't set it on the result of clang_getCursorDefinition for
4097 // a reference of the same declaration.
4098 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4099 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4100 // to provide that kind of info.
4101 if (clang_isDeclaration(X.kind))
4102 X.data[1] = 0;
4103 if (clang_isDeclaration(Y.kind))
4104 Y.data[1] = 0;
4105
Guy Benyei11169dd2012-12-18 14:30:41 +00004106 return X == Y;
4107}
4108
4109unsigned clang_hashCursor(CXCursor C) {
4110 unsigned Index = 0;
4111 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4112 Index = 1;
4113
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004114 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 std::make_pair(C.kind, C.data[Index]));
4116}
4117
4118unsigned clang_isInvalid(enum CXCursorKind K) {
4119 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4120}
4121
4122unsigned clang_isDeclaration(enum CXCursorKind K) {
4123 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4124 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4125}
4126
4127unsigned clang_isReference(enum CXCursorKind K) {
4128 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4129}
4130
4131unsigned clang_isExpression(enum CXCursorKind K) {
4132 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4133}
4134
4135unsigned clang_isStatement(enum CXCursorKind K) {
4136 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4137}
4138
4139unsigned clang_isAttribute(enum CXCursorKind K) {
4140 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4141}
4142
4143unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4144 return K == CXCursor_TranslationUnit;
4145}
4146
4147unsigned clang_isPreprocessing(enum CXCursorKind K) {
4148 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4149}
4150
4151unsigned clang_isUnexposed(enum CXCursorKind K) {
4152 switch (K) {
4153 case CXCursor_UnexposedDecl:
4154 case CXCursor_UnexposedExpr:
4155 case CXCursor_UnexposedStmt:
4156 case CXCursor_UnexposedAttr:
4157 return true;
4158 default:
4159 return false;
4160 }
4161}
4162
4163CXCursorKind clang_getCursorKind(CXCursor C) {
4164 return C.kind;
4165}
4166
4167CXSourceLocation clang_getCursorLocation(CXCursor C) {
4168 if (clang_isReference(C.kind)) {
4169 switch (C.kind) {
4170 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004171 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004172 = getCursorObjCSuperClassRef(C);
4173 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4174 }
4175
4176 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004177 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004178 = getCursorObjCProtocolRef(C);
4179 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4180 }
4181
4182 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004183 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004184 = getCursorObjCClassRef(C);
4185 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4186 }
4187
4188 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004189 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4191 }
4192
4193 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004194 std::pair<const TemplateDecl *, SourceLocation> P =
4195 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4197 }
4198
4199 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004200 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4202 }
4203
4204 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004205 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4207 }
4208
4209 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004210 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4212 }
4213
4214 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004215 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 if (!BaseSpec)
4217 return clang_getNullLocation();
4218
4219 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4220 return cxloc::translateSourceLocation(getCursorContext(C),
4221 TSInfo->getTypeLoc().getBeginLoc());
4222
4223 return cxloc::translateSourceLocation(getCursorContext(C),
4224 BaseSpec->getLocStart());
4225 }
4226
4227 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004228 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004229 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4230 }
4231
4232 case CXCursor_OverloadedDeclRef:
4233 return cxloc::translateSourceLocation(getCursorContext(C),
4234 getCursorOverloadedDeclRef(C).second);
4235
4236 default:
4237 // FIXME: Need a way to enumerate all non-reference cases.
4238 llvm_unreachable("Missed a reference kind");
4239 }
4240 }
4241
4242 if (clang_isExpression(C.kind))
4243 return cxloc::translateSourceLocation(getCursorContext(C),
4244 getLocationFromExpr(getCursorExpr(C)));
4245
4246 if (clang_isStatement(C.kind))
4247 return cxloc::translateSourceLocation(getCursorContext(C),
4248 getCursorStmt(C)->getLocStart());
4249
4250 if (C.kind == CXCursor_PreprocessingDirective) {
4251 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4252 return cxloc::translateSourceLocation(getCursorContext(C), L);
4253 }
4254
4255 if (C.kind == CXCursor_MacroExpansion) {
4256 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004257 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004258 return cxloc::translateSourceLocation(getCursorContext(C), L);
4259 }
4260
4261 if (C.kind == CXCursor_MacroDefinition) {
4262 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4263 return cxloc::translateSourceLocation(getCursorContext(C), L);
4264 }
4265
4266 if (C.kind == CXCursor_InclusionDirective) {
4267 SourceLocation L
4268 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4269 return cxloc::translateSourceLocation(getCursorContext(C), L);
4270 }
4271
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004272 if (clang_isAttribute(C.kind)) {
4273 SourceLocation L
4274 = cxcursor::getCursorAttr(C)->getLocation();
4275 return cxloc::translateSourceLocation(getCursorContext(C), L);
4276 }
4277
Guy Benyei11169dd2012-12-18 14:30:41 +00004278 if (!clang_isDeclaration(C.kind))
4279 return clang_getNullLocation();
4280
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004281 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004282 if (!D)
4283 return clang_getNullLocation();
4284
4285 SourceLocation Loc = D->getLocation();
4286 // FIXME: Multiple variables declared in a single declaration
4287 // currently lack the information needed to correctly determine their
4288 // ranges when accounting for the type-specifier. We use context
4289 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4290 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004291 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004292 if (!cxcursor::isFirstInDeclGroup(C))
4293 Loc = VD->getLocation();
4294 }
4295
4296 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004297 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004298 Loc = MD->getSelectorStartLoc();
4299
4300 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4301}
4302
4303} // end extern "C"
4304
4305CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4306 assert(TU);
4307
4308 // Guard against an invalid SourceLocation, or we may assert in one
4309 // of the following calls.
4310 if (SLoc.isInvalid())
4311 return clang_getNullCursor();
4312
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004313 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004314
4315 // Translate the given source location to make it point at the beginning of
4316 // the token under the cursor.
4317 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4318 CXXUnit->getASTContext().getLangOpts());
4319
4320 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4321 if (SLoc.isValid()) {
4322 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4323 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4324 /*VisitPreprocessorLast=*/true,
4325 /*VisitIncludedEntities=*/false,
4326 SourceLocation(SLoc));
4327 CursorVis.visitFileRegion();
4328 }
4329
4330 return Result;
4331}
4332
4333static SourceRange getRawCursorExtent(CXCursor C) {
4334 if (clang_isReference(C.kind)) {
4335 switch (C.kind) {
4336 case CXCursor_ObjCSuperClassRef:
4337 return getCursorObjCSuperClassRef(C).second;
4338
4339 case CXCursor_ObjCProtocolRef:
4340 return getCursorObjCProtocolRef(C).second;
4341
4342 case CXCursor_ObjCClassRef:
4343 return getCursorObjCClassRef(C).second;
4344
4345 case CXCursor_TypeRef:
4346 return getCursorTypeRef(C).second;
4347
4348 case CXCursor_TemplateRef:
4349 return getCursorTemplateRef(C).second;
4350
4351 case CXCursor_NamespaceRef:
4352 return getCursorNamespaceRef(C).second;
4353
4354 case CXCursor_MemberRef:
4355 return getCursorMemberRef(C).second;
4356
4357 case CXCursor_CXXBaseSpecifier:
4358 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4359
4360 case CXCursor_LabelRef:
4361 return getCursorLabelRef(C).second;
4362
4363 case CXCursor_OverloadedDeclRef:
4364 return getCursorOverloadedDeclRef(C).second;
4365
4366 case CXCursor_VariableRef:
4367 return getCursorVariableRef(C).second;
4368
4369 default:
4370 // FIXME: Need a way to enumerate all non-reference cases.
4371 llvm_unreachable("Missed a reference kind");
4372 }
4373 }
4374
4375 if (clang_isExpression(C.kind))
4376 return getCursorExpr(C)->getSourceRange();
4377
4378 if (clang_isStatement(C.kind))
4379 return getCursorStmt(C)->getSourceRange();
4380
4381 if (clang_isAttribute(C.kind))
4382 return getCursorAttr(C)->getRange();
4383
4384 if (C.kind == CXCursor_PreprocessingDirective)
4385 return cxcursor::getCursorPreprocessingDirective(C);
4386
4387 if (C.kind == CXCursor_MacroExpansion) {
4388 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004389 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004390 return TU->mapRangeFromPreamble(Range);
4391 }
4392
4393 if (C.kind == CXCursor_MacroDefinition) {
4394 ASTUnit *TU = getCursorASTUnit(C);
4395 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4396 return TU->mapRangeFromPreamble(Range);
4397 }
4398
4399 if (C.kind == CXCursor_InclusionDirective) {
4400 ASTUnit *TU = getCursorASTUnit(C);
4401 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4402 return TU->mapRangeFromPreamble(Range);
4403 }
4404
4405 if (C.kind == CXCursor_TranslationUnit) {
4406 ASTUnit *TU = getCursorASTUnit(C);
4407 FileID MainID = TU->getSourceManager().getMainFileID();
4408 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4409 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4410 return SourceRange(Start, End);
4411 }
4412
4413 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004414 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004415 if (!D)
4416 return SourceRange();
4417
4418 SourceRange R = D->getSourceRange();
4419 // FIXME: Multiple variables declared in a single declaration
4420 // currently lack the information needed to correctly determine their
4421 // ranges when accounting for the type-specifier. We use context
4422 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4423 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004424 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004425 if (!cxcursor::isFirstInDeclGroup(C))
4426 R.setBegin(VD->getLocation());
4427 }
4428 return R;
4429 }
4430 return SourceRange();
4431}
4432
4433/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4434/// the decl-specifier-seq for declarations.
4435static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4436 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004437 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004438 if (!D)
4439 return SourceRange();
4440
4441 SourceRange R = D->getSourceRange();
4442
4443 // Adjust the start of the location for declarations preceded by
4444 // declaration specifiers.
4445 SourceLocation StartLoc;
4446 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4447 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4448 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004449 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004450 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4451 StartLoc = TI->getTypeLoc().getLocStart();
4452 }
4453
4454 if (StartLoc.isValid() && R.getBegin().isValid() &&
4455 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4456 R.setBegin(StartLoc);
4457
4458 // FIXME: Multiple variables declared in a single declaration
4459 // currently lack the information needed to correctly determine their
4460 // ranges when accounting for the type-specifier. We use context
4461 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4462 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004463 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004464 if (!cxcursor::isFirstInDeclGroup(C))
4465 R.setBegin(VD->getLocation());
4466 }
4467
4468 return R;
4469 }
4470
4471 return getRawCursorExtent(C);
4472}
4473
4474extern "C" {
4475
4476CXSourceRange clang_getCursorExtent(CXCursor C) {
4477 SourceRange R = getRawCursorExtent(C);
4478 if (R.isInvalid())
4479 return clang_getNullRange();
4480
4481 return cxloc::translateSourceRange(getCursorContext(C), R);
4482}
4483
4484CXCursor clang_getCursorReferenced(CXCursor C) {
4485 if (clang_isInvalid(C.kind))
4486 return clang_getNullCursor();
4487
4488 CXTranslationUnit tu = getCursorTU(C);
4489 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004490 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004491 if (!D)
4492 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004493 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004494 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004495 if (const ObjCPropertyImplDecl *PropImpl =
4496 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004497 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4498 return MakeCXCursor(Property, tu);
4499
4500 return C;
4501 }
4502
4503 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004504 const Expr *E = getCursorExpr(C);
4505 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004506 if (D) {
4507 CXCursor declCursor = MakeCXCursor(D, tu);
4508 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4509 declCursor);
4510 return declCursor;
4511 }
4512
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004513 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004514 return MakeCursorOverloadedDeclRef(Ovl, tu);
4515
4516 return clang_getNullCursor();
4517 }
4518
4519 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004520 const Stmt *S = getCursorStmt(C);
4521 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004522 if (LabelDecl *label = Goto->getLabel())
4523 if (LabelStmt *labelS = label->getStmt())
4524 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4525
4526 return clang_getNullCursor();
4527 }
4528
4529 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004530 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004531 return MakeMacroDefinitionCursor(Def, tu);
4532 }
4533
4534 if (!clang_isReference(C.kind))
4535 return clang_getNullCursor();
4536
4537 switch (C.kind) {
4538 case CXCursor_ObjCSuperClassRef:
4539 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4540
4541 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004542 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4543 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004544 return MakeCXCursor(Def, tu);
4545
4546 return MakeCXCursor(Prot, tu);
4547 }
4548
4549 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004550 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4551 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004552 return MakeCXCursor(Def, tu);
4553
4554 return MakeCXCursor(Class, tu);
4555 }
4556
4557 case CXCursor_TypeRef:
4558 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4559
4560 case CXCursor_TemplateRef:
4561 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4562
4563 case CXCursor_NamespaceRef:
4564 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4565
4566 case CXCursor_MemberRef:
4567 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4568
4569 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004570 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004571 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4572 tu ));
4573 }
4574
4575 case CXCursor_LabelRef:
4576 // FIXME: We end up faking the "parent" declaration here because we
4577 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004578 return MakeCXCursor(getCursorLabelRef(C).first,
4579 cxtu::getASTUnit(tu)->getASTContext()
4580 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 tu);
4582
4583 case CXCursor_OverloadedDeclRef:
4584 return C;
4585
4586 case CXCursor_VariableRef:
4587 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4588
4589 default:
4590 // We would prefer to enumerate all non-reference cursor kinds here.
4591 llvm_unreachable("Unhandled reference cursor kind");
4592 }
4593}
4594
4595CXCursor clang_getCursorDefinition(CXCursor C) {
4596 if (clang_isInvalid(C.kind))
4597 return clang_getNullCursor();
4598
4599 CXTranslationUnit TU = getCursorTU(C);
4600
4601 bool WasReference = false;
4602 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4603 C = clang_getCursorReferenced(C);
4604 WasReference = true;
4605 }
4606
4607 if (C.kind == CXCursor_MacroExpansion)
4608 return clang_getCursorReferenced(C);
4609
4610 if (!clang_isDeclaration(C.kind))
4611 return clang_getNullCursor();
4612
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004613 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004614 if (!D)
4615 return clang_getNullCursor();
4616
4617 switch (D->getKind()) {
4618 // Declaration kinds that don't really separate the notions of
4619 // declaration and definition.
4620 case Decl::Namespace:
4621 case Decl::Typedef:
4622 case Decl::TypeAlias:
4623 case Decl::TypeAliasTemplate:
4624 case Decl::TemplateTypeParm:
4625 case Decl::EnumConstant:
4626 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004627 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004628 case Decl::IndirectField:
4629 case Decl::ObjCIvar:
4630 case Decl::ObjCAtDefsField:
4631 case Decl::ImplicitParam:
4632 case Decl::ParmVar:
4633 case Decl::NonTypeTemplateParm:
4634 case Decl::TemplateTemplateParm:
4635 case Decl::ObjCCategoryImpl:
4636 case Decl::ObjCImplementation:
4637 case Decl::AccessSpec:
4638 case Decl::LinkageSpec:
4639 case Decl::ObjCPropertyImpl:
4640 case Decl::FileScopeAsm:
4641 case Decl::StaticAssert:
4642 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004643 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004644 case Decl::Label: // FIXME: Is this right??
4645 case Decl::ClassScopeFunctionSpecialization:
4646 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004647 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004648 return C;
4649
4650 // Declaration kinds that don't make any sense here, but are
4651 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004652 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 case Decl::TranslationUnit:
4654 break;
4655
4656 // Declaration kinds for which the definition is not resolvable.
4657 case Decl::UnresolvedUsingTypename:
4658 case Decl::UnresolvedUsingValue:
4659 break;
4660
4661 case Decl::UsingDirective:
4662 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4663 TU);
4664
4665 case Decl::NamespaceAlias:
4666 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4667
4668 case Decl::Enum:
4669 case Decl::Record:
4670 case Decl::CXXRecord:
4671 case Decl::ClassTemplateSpecialization:
4672 case Decl::ClassTemplatePartialSpecialization:
4673 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4674 return MakeCXCursor(Def, TU);
4675 return clang_getNullCursor();
4676
4677 case Decl::Function:
4678 case Decl::CXXMethod:
4679 case Decl::CXXConstructor:
4680 case Decl::CXXDestructor:
4681 case Decl::CXXConversion: {
4682 const FunctionDecl *Def = 0;
4683 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004684 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004685 return clang_getNullCursor();
4686 }
4687
Larisse Voufo39a1e502013-08-06 01:03:05 +00004688 case Decl::Var:
4689 case Decl::VarTemplateSpecialization:
4690 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004692 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004693 return MakeCXCursor(Def, TU);
4694 return clang_getNullCursor();
4695 }
4696
4697 case Decl::FunctionTemplate: {
4698 const FunctionDecl *Def = 0;
4699 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4700 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4701 return clang_getNullCursor();
4702 }
4703
4704 case Decl::ClassTemplate: {
4705 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4706 ->getDefinition())
4707 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4708 TU);
4709 return clang_getNullCursor();
4710 }
4711
Larisse Voufo39a1e502013-08-06 01:03:05 +00004712 case Decl::VarTemplate: {
4713 if (VarDecl *Def =
4714 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4715 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4716 return clang_getNullCursor();
4717 }
4718
Guy Benyei11169dd2012-12-18 14:30:41 +00004719 case Decl::Using:
4720 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4721 D->getLocation(), TU);
4722
4723 case Decl::UsingShadow:
4724 return clang_getCursorDefinition(
4725 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4726 TU));
4727
4728 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004729 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004730 if (Method->isThisDeclarationADefinition())
4731 return C;
4732
4733 // Dig out the method definition in the associated
4734 // @implementation, if we have it.
4735 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004736 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004737 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4738 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4739 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4740 Method->isInstanceMethod()))
4741 if (Def->isThisDeclarationADefinition())
4742 return MakeCXCursor(Def, TU);
4743
4744 return clang_getNullCursor();
4745 }
4746
4747 case Decl::ObjCCategory:
4748 if (ObjCCategoryImplDecl *Impl
4749 = cast<ObjCCategoryDecl>(D)->getImplementation())
4750 return MakeCXCursor(Impl, TU);
4751 return clang_getNullCursor();
4752
4753 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004754 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004755 return MakeCXCursor(Def, TU);
4756 return clang_getNullCursor();
4757
4758 case Decl::ObjCInterface: {
4759 // There are two notions of a "definition" for an Objective-C
4760 // class: the interface and its implementation. When we resolved a
4761 // reference to an Objective-C class, produce the @interface as
4762 // the definition; when we were provided with the interface,
4763 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004764 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004765 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004766 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004767 return MakeCXCursor(Def, TU);
4768 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4769 return MakeCXCursor(Impl, TU);
4770 return clang_getNullCursor();
4771 }
4772
4773 case Decl::ObjCProperty:
4774 // FIXME: We don't really know where to find the
4775 // ObjCPropertyImplDecls that implement this property.
4776 return clang_getNullCursor();
4777
4778 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004779 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004780 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004781 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004782 return MakeCXCursor(Def, TU);
4783
4784 return clang_getNullCursor();
4785
4786 case Decl::Friend:
4787 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4788 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4789 return clang_getNullCursor();
4790
4791 case Decl::FriendTemplate:
4792 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4793 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4794 return clang_getNullCursor();
4795 }
4796
4797 return clang_getNullCursor();
4798}
4799
4800unsigned clang_isCursorDefinition(CXCursor C) {
4801 if (!clang_isDeclaration(C.kind))
4802 return 0;
4803
4804 return clang_getCursorDefinition(C) == C;
4805}
4806
4807CXCursor clang_getCanonicalCursor(CXCursor C) {
4808 if (!clang_isDeclaration(C.kind))
4809 return C;
4810
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004811 if (const Decl *D = getCursorDecl(C)) {
4812 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004813 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4814 return MakeCXCursor(CatD, getCursorTU(C));
4815
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004816 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4817 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004818 return MakeCXCursor(IFD, getCursorTU(C));
4819
4820 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4821 }
4822
4823 return C;
4824}
4825
4826int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4827 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4828}
4829
4830unsigned clang_getNumOverloadedDecls(CXCursor C) {
4831 if (C.kind != CXCursor_OverloadedDeclRef)
4832 return 0;
4833
4834 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004835 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004836 return E->getNumDecls();
4837
4838 if (OverloadedTemplateStorage *S
4839 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4840 return S->size();
4841
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004842 const Decl *D = Storage.get<const Decl *>();
4843 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004844 return Using->shadow_size();
4845
4846 return 0;
4847}
4848
4849CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4850 if (cursor.kind != CXCursor_OverloadedDeclRef)
4851 return clang_getNullCursor();
4852
4853 if (index >= clang_getNumOverloadedDecls(cursor))
4854 return clang_getNullCursor();
4855
4856 CXTranslationUnit TU = getCursorTU(cursor);
4857 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004858 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004859 return MakeCXCursor(E->decls_begin()[index], TU);
4860
4861 if (OverloadedTemplateStorage *S
4862 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4863 return MakeCXCursor(S->begin()[index], TU);
4864
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004865 const Decl *D = Storage.get<const Decl *>();
4866 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004867 // FIXME: This is, unfortunately, linear time.
4868 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4869 std::advance(Pos, index);
4870 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4871 }
4872
4873 return clang_getNullCursor();
4874}
4875
4876void clang_getDefinitionSpellingAndExtent(CXCursor C,
4877 const char **startBuf,
4878 const char **endBuf,
4879 unsigned *startLine,
4880 unsigned *startColumn,
4881 unsigned *endLine,
4882 unsigned *endColumn) {
4883 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004884 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004885 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4886
4887 SourceManager &SM = FD->getASTContext().getSourceManager();
4888 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4889 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4890 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4891 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4892 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4893 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4894}
4895
4896
4897CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4898 unsigned PieceIndex) {
4899 RefNamePieces Pieces;
4900
4901 switch (C.kind) {
4902 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004903 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004904 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4905 E->getQualifierLoc().getSourceRange());
4906 break;
4907
4908 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004909 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004910 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4911 E->getQualifierLoc().getSourceRange(),
4912 E->getOptionalExplicitTemplateArgs());
4913 break;
4914
4915 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004916 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004917 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004918 const Expr *Callee = OCE->getCallee();
4919 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004920 Callee = ICE->getSubExpr();
4921
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004922 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004923 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4924 DRE->getQualifierLoc().getSourceRange());
4925 }
4926 break;
4927
4928 default:
4929 break;
4930 }
4931
4932 if (Pieces.empty()) {
4933 if (PieceIndex == 0)
4934 return clang_getCursorExtent(C);
4935 } else if (PieceIndex < Pieces.size()) {
4936 SourceRange R = Pieces[PieceIndex];
4937 if (R.isValid())
4938 return cxloc::translateSourceRange(getCursorContext(C), R);
4939 }
4940
4941 return clang_getNullRange();
4942}
4943
4944void clang_enableStackTraces(void) {
4945 llvm::sys::PrintStackTraceOnErrorSignal();
4946}
4947
4948void clang_executeOnThread(void (*fn)(void*), void *user_data,
4949 unsigned stack_size) {
4950 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4951}
4952
4953} // end: extern "C"
4954
4955//===----------------------------------------------------------------------===//
4956// Token-based Operations.
4957//===----------------------------------------------------------------------===//
4958
4959/* CXToken layout:
4960 * int_data[0]: a CXTokenKind
4961 * int_data[1]: starting token location
4962 * int_data[2]: token length
4963 * int_data[3]: reserved
4964 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4965 * otherwise unused.
4966 */
4967extern "C" {
4968
4969CXTokenKind clang_getTokenKind(CXToken CXTok) {
4970 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4971}
4972
4973CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4974 switch (clang_getTokenKind(CXTok)) {
4975 case CXToken_Identifier:
4976 case CXToken_Keyword:
4977 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004978 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004979 ->getNameStart());
4980
4981 case CXToken_Literal: {
4982 // We have stashed the starting pointer in the ptr_data field. Use it.
4983 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004984 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004985 }
4986
4987 case CXToken_Punctuation:
4988 case CXToken_Comment:
4989 break;
4990 }
4991
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004992 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004993 LOG_BAD_TU(TU);
4994 return cxstring::createEmpty();
4995 }
4996
Guy Benyei11169dd2012-12-18 14:30:41 +00004997 // We have to find the starting buffer pointer the hard way, by
4998 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004999 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005000 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005001 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005002
5003 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5004 std::pair<FileID, unsigned> LocInfo
5005 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5006 bool Invalid = false;
5007 StringRef Buffer
5008 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5009 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005010 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005011
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005012 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005013}
5014
5015CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005016 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005017 LOG_BAD_TU(TU);
5018 return clang_getNullLocation();
5019 }
5020
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005021 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005022 if (!CXXUnit)
5023 return clang_getNullLocation();
5024
5025 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5026 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5027}
5028
5029CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005030 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005031 LOG_BAD_TU(TU);
5032 return clang_getNullRange();
5033 }
5034
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005035 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005036 if (!CXXUnit)
5037 return clang_getNullRange();
5038
5039 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5040 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5041}
5042
5043static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5044 SmallVectorImpl<CXToken> &CXTokens) {
5045 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5046 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005047 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005048 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005049 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005050
5051 // Cannot tokenize across files.
5052 if (BeginLocInfo.first != EndLocInfo.first)
5053 return;
5054
5055 // Create a lexer
5056 bool Invalid = false;
5057 StringRef Buffer
5058 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5059 if (Invalid)
5060 return;
5061
5062 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5063 CXXUnit->getASTContext().getLangOpts(),
5064 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5065 Lex.SetCommentRetentionState(true);
5066
5067 // Lex tokens until we hit the end of the range.
5068 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5069 Token Tok;
5070 bool previousWasAt = false;
5071 do {
5072 // Lex the next token
5073 Lex.LexFromRawLexer(Tok);
5074 if (Tok.is(tok::eof))
5075 break;
5076
5077 // Initialize the CXToken.
5078 CXToken CXTok;
5079
5080 // - Common fields
5081 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5082 CXTok.int_data[2] = Tok.getLength();
5083 CXTok.int_data[3] = 0;
5084
5085 // - Kind-specific fields
5086 if (Tok.isLiteral()) {
5087 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005088 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005089 } else if (Tok.is(tok::raw_identifier)) {
5090 // Lookup the identifier to determine whether we have a keyword.
5091 IdentifierInfo *II
5092 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5093
5094 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5095 CXTok.int_data[0] = CXToken_Keyword;
5096 }
5097 else {
5098 CXTok.int_data[0] = Tok.is(tok::identifier)
5099 ? CXToken_Identifier
5100 : CXToken_Keyword;
5101 }
5102 CXTok.ptr_data = II;
5103 } else if (Tok.is(tok::comment)) {
5104 CXTok.int_data[0] = CXToken_Comment;
5105 CXTok.ptr_data = 0;
5106 } else {
5107 CXTok.int_data[0] = CXToken_Punctuation;
5108 CXTok.ptr_data = 0;
5109 }
5110 CXTokens.push_back(CXTok);
5111 previousWasAt = Tok.is(tok::at);
5112 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5113}
5114
5115void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5116 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005117 LOG_FUNC_SECTION {
5118 *Log << TU << ' ' << Range;
5119 }
5120
Guy Benyei11169dd2012-12-18 14:30:41 +00005121 if (Tokens)
5122 *Tokens = 0;
5123 if (NumTokens)
5124 *NumTokens = 0;
5125
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005126 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005127 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005128 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005129 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005130
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005131 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005132 if (!CXXUnit || !Tokens || !NumTokens)
5133 return;
5134
5135 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5136
5137 SourceRange R = cxloc::translateCXSourceRange(Range);
5138 if (R.isInvalid())
5139 return;
5140
5141 SmallVector<CXToken, 32> CXTokens;
5142 getTokens(CXXUnit, R, CXTokens);
5143
5144 if (CXTokens.empty())
5145 return;
5146
5147 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5148 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5149 *NumTokens = CXTokens.size();
5150}
5151
5152void clang_disposeTokens(CXTranslationUnit TU,
5153 CXToken *Tokens, unsigned NumTokens) {
5154 free(Tokens);
5155}
5156
5157} // end: extern "C"
5158
5159//===----------------------------------------------------------------------===//
5160// Token annotation APIs.
5161//===----------------------------------------------------------------------===//
5162
Guy Benyei11169dd2012-12-18 14:30:41 +00005163static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5164 CXCursor parent,
5165 CXClientData client_data);
5166static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5167 CXClientData client_data);
5168
5169namespace {
5170class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005171 CXToken *Tokens;
5172 CXCursor *Cursors;
5173 unsigned NumTokens;
5174 unsigned TokIdx;
5175 unsigned PreprocessingTokIdx;
5176 CursorVisitor AnnotateVis;
5177 SourceManager &SrcMgr;
5178 bool HasContextSensitiveKeywords;
5179
5180 struct PostChildrenInfo {
5181 CXCursor Cursor;
5182 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005183 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005184 unsigned BeforeChildrenTokenIdx;
5185 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005186 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005187
5188 CXToken &getTok(unsigned Idx) {
5189 assert(Idx < NumTokens);
5190 return Tokens[Idx];
5191 }
5192 const CXToken &getTok(unsigned Idx) const {
5193 assert(Idx < NumTokens);
5194 return Tokens[Idx];
5195 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005196 bool MoreTokens() const { return TokIdx < NumTokens; }
5197 unsigned NextToken() const { return TokIdx; }
5198 void AdvanceToken() { ++TokIdx; }
5199 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005200 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005201 }
5202 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005203 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 }
5205 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005206 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005207 }
5208
5209 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005210 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005211 SourceRange);
5212
5213public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005214 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005215 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005216 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005217 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005218 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005219 AnnotateTokensVisitor, this,
5220 /*VisitPreprocessorLast=*/true,
5221 /*VisitIncludedEntities=*/false,
5222 RegionOfInterest,
5223 /*VisitDeclsOnly=*/false,
5224 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005225 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005226 HasContextSensitiveKeywords(false) { }
5227
5228 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5229 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5230 bool postVisitChildren(CXCursor cursor);
5231 void AnnotateTokens();
5232
5233 /// \brief Determine whether the annotator saw any cursors that have
5234 /// context-sensitive keywords.
5235 bool hasContextSensitiveKeywords() const {
5236 return HasContextSensitiveKeywords;
5237 }
5238
5239 ~AnnotateTokensWorker() {
5240 assert(PostChildrenInfos.empty());
5241 }
5242};
5243}
5244
5245void AnnotateTokensWorker::AnnotateTokens() {
5246 // Walk the AST within the region of interest, annotating tokens
5247 // along the way.
5248 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005249}
Guy Benyei11169dd2012-12-18 14:30:41 +00005250
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005251static inline void updateCursorAnnotation(CXCursor &Cursor,
5252 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005253 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005254 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005255 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005256}
5257
5258/// \brief It annotates and advances tokens with a cursor until the comparison
5259//// between the cursor location and the source range is the same as
5260/// \arg compResult.
5261///
5262/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5263/// Pass RangeOverlap to annotate tokens inside a range.
5264void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5265 RangeComparisonResult compResult,
5266 SourceRange range) {
5267 while (MoreTokens()) {
5268 const unsigned I = NextToken();
5269 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005270 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5271 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005272
5273 SourceLocation TokLoc = GetTokenLoc(I);
5274 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005275 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005276 AdvanceToken();
5277 continue;
5278 }
5279 break;
5280 }
5281}
5282
5283/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005284/// \returns true if it advanced beyond all macro tokens, false otherwise.
5285bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005286 CXCursor updateC,
5287 RangeComparisonResult compResult,
5288 SourceRange range) {
5289 assert(MoreTokens());
5290 assert(isFunctionMacroToken(NextToken()) &&
5291 "Should be called only for macro arg tokens");
5292
5293 // This works differently than annotateAndAdvanceTokens; because expanded
5294 // macro arguments can have arbitrary translation-unit source order, we do not
5295 // advance the token index one by one until a token fails the range test.
5296 // We only advance once past all of the macro arg tokens if all of them
5297 // pass the range test. If one of them fails we keep the token index pointing
5298 // at the start of the macro arg tokens so that the failing token will be
5299 // annotated by a subsequent annotation try.
5300
5301 bool atLeastOneCompFail = false;
5302
5303 unsigned I = NextToken();
5304 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5305 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5306 if (TokLoc.isFileID())
5307 continue; // not macro arg token, it's parens or comma.
5308 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5309 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5310 Cursors[I] = updateC;
5311 } else
5312 atLeastOneCompFail = true;
5313 }
5314
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005315 if (atLeastOneCompFail)
5316 return false;
5317
5318 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5319 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005320}
5321
5322enum CXChildVisitResult
5323AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005324 SourceRange cursorRange = getRawCursorExtent(cursor);
5325 if (cursorRange.isInvalid())
5326 return CXChildVisit_Recurse;
5327
5328 if (!HasContextSensitiveKeywords) {
5329 // Objective-C properties can have context-sensitive keywords.
5330 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005331 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005332 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5333 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5334 }
5335 // Objective-C methods can have context-sensitive keywords.
5336 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5337 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005338 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005339 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5340 if (Method->getObjCDeclQualifier())
5341 HasContextSensitiveKeywords = true;
5342 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005343 for (const auto *P : Method->params()) {
5344 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005345 HasContextSensitiveKeywords = true;
5346 break;
5347 }
5348 }
5349 }
5350 }
5351 }
5352 // C++ methods can have context-sensitive keywords.
5353 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005354 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005355 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5356 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5357 HasContextSensitiveKeywords = true;
5358 }
5359 }
5360 // C++ classes can have context-sensitive keywords.
5361 else if (cursor.kind == CXCursor_StructDecl ||
5362 cursor.kind == CXCursor_ClassDecl ||
5363 cursor.kind == CXCursor_ClassTemplate ||
5364 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005365 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005366 if (D->hasAttr<FinalAttr>())
5367 HasContextSensitiveKeywords = true;
5368 }
5369 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005370
5371 // Don't override a property annotation with its getter/setter method.
5372 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5373 parent.kind == CXCursor_ObjCPropertyDecl)
5374 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005375
5376 if (clang_isPreprocessing(cursor.kind)) {
5377 // Items in the preprocessing record are kept separate from items in
5378 // declarations, so we keep a separate token index.
5379 unsigned SavedTokIdx = TokIdx;
5380 TokIdx = PreprocessingTokIdx;
5381
5382 // Skip tokens up until we catch up to the beginning of the preprocessing
5383 // entry.
5384 while (MoreTokens()) {
5385 const unsigned I = NextToken();
5386 SourceLocation TokLoc = GetTokenLoc(I);
5387 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5388 case RangeBefore:
5389 AdvanceToken();
5390 continue;
5391 case RangeAfter:
5392 case RangeOverlap:
5393 break;
5394 }
5395 break;
5396 }
5397
5398 // Look at all of the tokens within this range.
5399 while (MoreTokens()) {
5400 const unsigned I = NextToken();
5401 SourceLocation TokLoc = GetTokenLoc(I);
5402 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5403 case RangeBefore:
5404 llvm_unreachable("Infeasible");
5405 case RangeAfter:
5406 break;
5407 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005408 // For macro expansions, just note where the beginning of the macro
5409 // expansion occurs.
5410 if (cursor.kind == CXCursor_MacroExpansion) {
5411 if (TokLoc == cursorRange.getBegin())
5412 Cursors[I] = cursor;
5413 AdvanceToken();
5414 break;
5415 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005416 // We may have already annotated macro names inside macro definitions.
5417 if (Cursors[I].kind != CXCursor_MacroExpansion)
5418 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005419 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005420 continue;
5421 }
5422 break;
5423 }
5424
5425 // Save the preprocessing token index; restore the non-preprocessing
5426 // token index.
5427 PreprocessingTokIdx = TokIdx;
5428 TokIdx = SavedTokIdx;
5429 return CXChildVisit_Recurse;
5430 }
5431
5432 if (cursorRange.isInvalid())
5433 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005434
5435 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005436 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005437 const enum CXCursorKind K = clang_getCursorKind(parent);
5438 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005439 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5440 // Attributes are annotated out-of-order, skip tokens until we reach it.
5441 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005442 ? clang_getNullCursor() : parent;
5443
5444 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5445
5446 // Avoid having the cursor of an expression "overwrite" the annotation of the
5447 // variable declaration that it belongs to.
5448 // This can happen for C++ constructor expressions whose range generally
5449 // include the variable declaration, e.g.:
5450 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005451 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005452 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005453 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005454 const unsigned I = NextToken();
5455 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5456 E->getLocStart() == D->getLocation() &&
5457 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005458 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005459 AdvanceToken();
5460 }
5461 }
5462 }
5463
5464 // Before recursing into the children keep some state that we are going
5465 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5466 // extra work after the child nodes are visited.
5467 // Note that we don't call VisitChildren here to avoid traversing statements
5468 // code-recursively which can blow the stack.
5469
5470 PostChildrenInfo Info;
5471 Info.Cursor = cursor;
5472 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005473 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005474 Info.BeforeChildrenTokenIdx = NextToken();
5475 PostChildrenInfos.push_back(Info);
5476
5477 return CXChildVisit_Recurse;
5478}
5479
5480bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5481 if (PostChildrenInfos.empty())
5482 return false;
5483 const PostChildrenInfo &Info = PostChildrenInfos.back();
5484 if (!clang_equalCursors(Info.Cursor, cursor))
5485 return false;
5486
5487 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5488 const unsigned AfterChildren = NextToken();
5489 SourceRange cursorRange = Info.CursorRange;
5490
5491 // Scan the tokens that are at the end of the cursor, but are not captured
5492 // but the child cursors.
5493 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5494
5495 // Scan the tokens that are at the beginning of the cursor, but are not
5496 // capture by the child cursors.
5497 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5498 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5499 break;
5500
5501 Cursors[I] = cursor;
5502 }
5503
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005504 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5505 // encountered the attribute cursor.
5506 if (clang_isAttribute(cursor.kind))
5507 TokIdx = Info.BeforeReachingCursorIdx;
5508
Guy Benyei11169dd2012-12-18 14:30:41 +00005509 PostChildrenInfos.pop_back();
5510 return false;
5511}
5512
5513static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5514 CXCursor parent,
5515 CXClientData client_data) {
5516 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5517}
5518
5519static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5520 CXClientData client_data) {
5521 return static_cast<AnnotateTokensWorker*>(client_data)->
5522 postVisitChildren(cursor);
5523}
5524
5525namespace {
5526
5527/// \brief Uses the macro expansions in the preprocessing record to find
5528/// and mark tokens that are macro arguments. This info is used by the
5529/// AnnotateTokensWorker.
5530class MarkMacroArgTokensVisitor {
5531 SourceManager &SM;
5532 CXToken *Tokens;
5533 unsigned NumTokens;
5534 unsigned CurIdx;
5535
5536public:
5537 MarkMacroArgTokensVisitor(SourceManager &SM,
5538 CXToken *tokens, unsigned numTokens)
5539 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5540
5541 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5542 if (cursor.kind != CXCursor_MacroExpansion)
5543 return CXChildVisit_Continue;
5544
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005545 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005546 if (macroRange.getBegin() == macroRange.getEnd())
5547 return CXChildVisit_Continue; // it's not a function macro.
5548
5549 for (; CurIdx < NumTokens; ++CurIdx) {
5550 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5551 macroRange.getBegin()))
5552 break;
5553 }
5554
5555 if (CurIdx == NumTokens)
5556 return CXChildVisit_Break;
5557
5558 for (; CurIdx < NumTokens; ++CurIdx) {
5559 SourceLocation tokLoc = getTokenLoc(CurIdx);
5560 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5561 break;
5562
5563 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5564 }
5565
5566 if (CurIdx == NumTokens)
5567 return CXChildVisit_Break;
5568
5569 return CXChildVisit_Continue;
5570 }
5571
5572private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005573 CXToken &getTok(unsigned Idx) {
5574 assert(Idx < NumTokens);
5575 return Tokens[Idx];
5576 }
5577 const CXToken &getTok(unsigned Idx) const {
5578 assert(Idx < NumTokens);
5579 return Tokens[Idx];
5580 }
5581
Guy Benyei11169dd2012-12-18 14:30:41 +00005582 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005583 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005584 }
5585
5586 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5587 // The third field is reserved and currently not used. Use it here
5588 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005589 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005590 }
5591};
5592
5593} // end anonymous namespace
5594
5595static CXChildVisitResult
5596MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5597 CXClientData client_data) {
5598 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5599 parent);
5600}
5601
5602namespace {
5603 struct clang_annotateTokens_Data {
5604 CXTranslationUnit TU;
5605 ASTUnit *CXXUnit;
5606 CXToken *Tokens;
5607 unsigned NumTokens;
5608 CXCursor *Cursors;
5609 };
5610}
5611
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005612/// \brief Used by \c annotatePreprocessorTokens.
5613/// \returns true if lexing was finished, false otherwise.
5614static bool lexNext(Lexer &Lex, Token &Tok,
5615 unsigned &NextIdx, unsigned NumTokens) {
5616 if (NextIdx >= NumTokens)
5617 return true;
5618
5619 ++NextIdx;
5620 Lex.LexFromRawLexer(Tok);
5621 if (Tok.is(tok::eof))
5622 return true;
5623
5624 return false;
5625}
5626
Guy Benyei11169dd2012-12-18 14:30:41 +00005627static void annotatePreprocessorTokens(CXTranslationUnit TU,
5628 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005629 CXCursor *Cursors,
5630 CXToken *Tokens,
5631 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005632 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005633
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005634 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005635 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5636 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005637 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005638 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005639 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005640
5641 if (BeginLocInfo.first != EndLocInfo.first)
5642 return;
5643
5644 StringRef Buffer;
5645 bool Invalid = false;
5646 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5647 if (Buffer.empty() || Invalid)
5648 return;
5649
5650 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5651 CXXUnit->getASTContext().getLangOpts(),
5652 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5653 Buffer.end());
5654 Lex.SetCommentRetentionState(true);
5655
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005656 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005657 // Lex tokens in raw mode until we hit the end of the range, to avoid
5658 // entering #includes or expanding macros.
5659 while (true) {
5660 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005661 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5662 break;
5663 unsigned TokIdx = NextIdx-1;
5664 assert(Tok.getLocation() ==
5665 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005666
5667 reprocess:
5668 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005669 // We have found a preprocessing directive. Annotate the tokens
5670 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005671 //
5672 // FIXME: Some simple tests here could identify macro definitions and
5673 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005674
5675 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005676 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5677 break;
5678
5679 MacroInfo *MI = 0;
5680 if (Tok.is(tok::raw_identifier) &&
5681 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5682 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5683 break;
5684
5685 if (Tok.is(tok::raw_identifier)) {
5686 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5687 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5688 SourceLocation MappedTokLoc =
5689 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5690 MI = getMacroInfo(II, MappedTokLoc, TU);
5691 }
5692 }
5693
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005694 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005695 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005696 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5697 finished = true;
5698 break;
5699 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005700 // If we are in a macro definition, check if the token was ever a
5701 // macro name and annotate it if that's the case.
5702 if (MI) {
5703 SourceLocation SaveLoc = Tok.getLocation();
5704 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5705 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5706 Tok.setLocation(SaveLoc);
5707 if (MacroDef)
5708 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5709 Tok.getLocation(), TU);
5710 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005711 } while (!Tok.isAtStartOfLine());
5712
5713 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5714 assert(TokIdx <= LastIdx);
5715 SourceLocation EndLoc =
5716 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5717 CXCursor Cursor =
5718 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5719
5720 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005721 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005722
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005723 if (finished)
5724 break;
5725 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005726 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005727 }
5728}
5729
5730// This gets run a separate thread to avoid stack blowout.
5731static void clang_annotateTokensImpl(void *UserData) {
5732 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5733 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5734 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5735 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5736 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5737
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005738 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005739 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5740 setThreadBackgroundPriority();
5741
5742 // Determine the region of interest, which contains all of the tokens.
5743 SourceRange RegionOfInterest;
5744 RegionOfInterest.setBegin(
5745 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5746 RegionOfInterest.setEnd(
5747 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5748 Tokens[NumTokens-1])));
5749
Guy Benyei11169dd2012-12-18 14:30:41 +00005750 // Relex the tokens within the source range to look for preprocessing
5751 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005752 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005753
5754 // If begin location points inside a macro argument, set it to the expansion
5755 // location so we can have the full context when annotating semantically.
5756 {
5757 SourceManager &SM = CXXUnit->getSourceManager();
5758 SourceLocation Loc =
5759 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5760 if (Loc.isMacroID())
5761 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5762 }
5763
Guy Benyei11169dd2012-12-18 14:30:41 +00005764 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5765 // Search and mark tokens that are macro argument expansions.
5766 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5767 Tokens, NumTokens);
5768 CursorVisitor MacroArgMarker(TU,
5769 MarkMacroArgTokensVisitorDelegate, &Visitor,
5770 /*VisitPreprocessorLast=*/true,
5771 /*VisitIncludedEntities=*/false,
5772 RegionOfInterest);
5773 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5774 }
5775
5776 // Annotate all of the source locations in the region of interest that map to
5777 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005778 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005779
5780 // FIXME: We use a ridiculous stack size here because the data-recursion
5781 // algorithm uses a large stack frame than the non-data recursive version,
5782 // and AnnotationTokensWorker currently transforms the data-recursion
5783 // algorithm back into a traditional recursion by explicitly calling
5784 // VisitChildren(). We will need to remove this explicit recursive call.
5785 W.AnnotateTokens();
5786
5787 // If we ran into any entities that involve context-sensitive keywords,
5788 // take another pass through the tokens to mark them as such.
5789 if (W.hasContextSensitiveKeywords()) {
5790 for (unsigned I = 0; I != NumTokens; ++I) {
5791 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5792 continue;
5793
5794 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5795 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005796 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005797 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5798 if (Property->getPropertyAttributesAsWritten() != 0 &&
5799 llvm::StringSwitch<bool>(II->getName())
5800 .Case("readonly", true)
5801 .Case("assign", true)
5802 .Case("unsafe_unretained", true)
5803 .Case("readwrite", true)
5804 .Case("retain", true)
5805 .Case("copy", true)
5806 .Case("nonatomic", true)
5807 .Case("atomic", true)
5808 .Case("getter", true)
5809 .Case("setter", true)
5810 .Case("strong", true)
5811 .Case("weak", true)
5812 .Default(false))
5813 Tokens[I].int_data[0] = CXToken_Keyword;
5814 }
5815 continue;
5816 }
5817
5818 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5819 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5820 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5821 if (llvm::StringSwitch<bool>(II->getName())
5822 .Case("in", true)
5823 .Case("out", true)
5824 .Case("inout", true)
5825 .Case("oneway", true)
5826 .Case("bycopy", true)
5827 .Case("byref", true)
5828 .Default(false))
5829 Tokens[I].int_data[0] = CXToken_Keyword;
5830 continue;
5831 }
5832
5833 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5834 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5835 Tokens[I].int_data[0] = CXToken_Keyword;
5836 continue;
5837 }
5838 }
5839 }
5840}
5841
5842extern "C" {
5843
5844void clang_annotateTokens(CXTranslationUnit TU,
5845 CXToken *Tokens, unsigned NumTokens,
5846 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005847 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005848 LOG_BAD_TU(TU);
5849 return;
5850 }
5851 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005852 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005853 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005854 }
5855
5856 LOG_FUNC_SECTION {
5857 *Log << TU << ' ';
5858 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5859 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5860 *Log << clang_getRange(bloc, eloc);
5861 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005862
5863 // Any token we don't specifically annotate will have a NULL cursor.
5864 CXCursor C = clang_getNullCursor();
5865 for (unsigned I = 0; I != NumTokens; ++I)
5866 Cursors[I] = C;
5867
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005868 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005869 if (!CXXUnit)
5870 return;
5871
5872 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5873
5874 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5875 llvm::CrashRecoveryContext CRC;
5876 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5877 GetSafetyThreadStackSize() * 2)) {
5878 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5879 }
5880}
5881
5882} // end: extern "C"
5883
5884//===----------------------------------------------------------------------===//
5885// Operations for querying linkage of a cursor.
5886//===----------------------------------------------------------------------===//
5887
5888extern "C" {
5889CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5890 if (!clang_isDeclaration(cursor.kind))
5891 return CXLinkage_Invalid;
5892
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005893 const Decl *D = cxcursor::getCursorDecl(cursor);
5894 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005895 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005896 case NoLinkage:
5897 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005898 case InternalLinkage: return CXLinkage_Internal;
5899 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5900 case ExternalLinkage: return CXLinkage_External;
5901 };
5902
5903 return CXLinkage_Invalid;
5904}
5905} // end: extern "C"
5906
5907//===----------------------------------------------------------------------===//
5908// Operations for querying language of a cursor.
5909//===----------------------------------------------------------------------===//
5910
5911static CXLanguageKind getDeclLanguage(const Decl *D) {
5912 if (!D)
5913 return CXLanguage_C;
5914
5915 switch (D->getKind()) {
5916 default:
5917 break;
5918 case Decl::ImplicitParam:
5919 case Decl::ObjCAtDefsField:
5920 case Decl::ObjCCategory:
5921 case Decl::ObjCCategoryImpl:
5922 case Decl::ObjCCompatibleAlias:
5923 case Decl::ObjCImplementation:
5924 case Decl::ObjCInterface:
5925 case Decl::ObjCIvar:
5926 case Decl::ObjCMethod:
5927 case Decl::ObjCProperty:
5928 case Decl::ObjCPropertyImpl:
5929 case Decl::ObjCProtocol:
5930 return CXLanguage_ObjC;
5931 case Decl::CXXConstructor:
5932 case Decl::CXXConversion:
5933 case Decl::CXXDestructor:
5934 case Decl::CXXMethod:
5935 case Decl::CXXRecord:
5936 case Decl::ClassTemplate:
5937 case Decl::ClassTemplatePartialSpecialization:
5938 case Decl::ClassTemplateSpecialization:
5939 case Decl::Friend:
5940 case Decl::FriendTemplate:
5941 case Decl::FunctionTemplate:
5942 case Decl::LinkageSpec:
5943 case Decl::Namespace:
5944 case Decl::NamespaceAlias:
5945 case Decl::NonTypeTemplateParm:
5946 case Decl::StaticAssert:
5947 case Decl::TemplateTemplateParm:
5948 case Decl::TemplateTypeParm:
5949 case Decl::UnresolvedUsingTypename:
5950 case Decl::UnresolvedUsingValue:
5951 case Decl::Using:
5952 case Decl::UsingDirective:
5953 case Decl::UsingShadow:
5954 return CXLanguage_CPlusPlus;
5955 }
5956
5957 return CXLanguage_C;
5958}
5959
5960extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005961
5962static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5963 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5964 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005965
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005966 switch (D->getAvailability()) {
5967 case AR_Available:
5968 case AR_NotYetIntroduced:
5969 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005970 return getCursorAvailabilityForDecl(
5971 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005972 return CXAvailability_Available;
5973
5974 case AR_Deprecated:
5975 return CXAvailability_Deprecated;
5976
5977 case AR_Unavailable:
5978 return CXAvailability_NotAvailable;
5979 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005980
5981 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005982}
5983
Guy Benyei11169dd2012-12-18 14:30:41 +00005984enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5985 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005986 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5987 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005988
5989 return CXAvailability_Available;
5990}
5991
5992static CXVersion convertVersion(VersionTuple In) {
5993 CXVersion Out = { -1, -1, -1 };
5994 if (In.empty())
5995 return Out;
5996
5997 Out.Major = In.getMajor();
5998
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005999 Optional<unsigned> Minor = In.getMinor();
6000 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006001 Out.Minor = *Minor;
6002 else
6003 return Out;
6004
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006005 Optional<unsigned> Subminor = In.getSubminor();
6006 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006007 Out.Subminor = *Subminor;
6008
6009 return Out;
6010}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006011
6012static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6013 int *always_deprecated,
6014 CXString *deprecated_message,
6015 int *always_unavailable,
6016 CXString *unavailable_message,
6017 CXPlatformAvailability *availability,
6018 int availability_size) {
6019 bool HadAvailAttr = false;
6020 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006021 for (auto A : D->attrs()) {
6022 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006023 HadAvailAttr = true;
6024 if (always_deprecated)
6025 *always_deprecated = 1;
6026 if (deprecated_message)
6027 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
6028 continue;
6029 }
6030
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006031 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006032 HadAvailAttr = true;
6033 if (always_unavailable)
6034 *always_unavailable = 1;
6035 if (unavailable_message) {
6036 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6037 }
6038 continue;
6039 }
6040
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006041 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006042 HadAvailAttr = true;
6043 if (N < availability_size) {
6044 availability[N].Platform
6045 = cxstring::createDup(Avail->getPlatform()->getName());
6046 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6047 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6048 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6049 availability[N].Unavailable = Avail->getUnavailable();
6050 availability[N].Message = cxstring::createDup(Avail->getMessage());
6051 }
6052 ++N;
6053 }
6054 }
6055
6056 if (!HadAvailAttr)
6057 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6058 return getCursorPlatformAvailabilityForDecl(
6059 cast<Decl>(EnumConst->getDeclContext()),
6060 always_deprecated,
6061 deprecated_message,
6062 always_unavailable,
6063 unavailable_message,
6064 availability,
6065 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006066
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006067 return N;
6068}
6069
Guy Benyei11169dd2012-12-18 14:30:41 +00006070int clang_getCursorPlatformAvailability(CXCursor cursor,
6071 int *always_deprecated,
6072 CXString *deprecated_message,
6073 int *always_unavailable,
6074 CXString *unavailable_message,
6075 CXPlatformAvailability *availability,
6076 int availability_size) {
6077 if (always_deprecated)
6078 *always_deprecated = 0;
6079 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006080 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006081 if (always_unavailable)
6082 *always_unavailable = 0;
6083 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006084 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006085
Guy Benyei11169dd2012-12-18 14:30:41 +00006086 if (!clang_isDeclaration(cursor.kind))
6087 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006088
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006089 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006090 if (!D)
6091 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006092
6093 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6094 deprecated_message,
6095 always_unavailable,
6096 unavailable_message,
6097 availability,
6098 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006099}
6100
6101void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6102 clang_disposeString(availability->Platform);
6103 clang_disposeString(availability->Message);
6104}
6105
6106CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6107 if (clang_isDeclaration(cursor.kind))
6108 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6109
6110 return CXLanguage_Invalid;
6111}
6112
6113 /// \brief If the given cursor is the "templated" declaration
6114 /// descibing a class or function template, return the class or
6115 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006116static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006117 if (!D)
6118 return 0;
6119
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006120 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006121 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6122 return FunTmpl;
6123
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006124 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006125 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6126 return ClassTmpl;
6127
6128 return D;
6129}
6130
6131CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6132 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006133 if (const Decl *D = getCursorDecl(cursor)) {
6134 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006135 if (!DC)
6136 return clang_getNullCursor();
6137
6138 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6139 getCursorTU(cursor));
6140 }
6141 }
6142
6143 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006144 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006145 return MakeCXCursor(D, getCursorTU(cursor));
6146 }
6147
6148 return clang_getNullCursor();
6149}
6150
6151CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6152 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006153 if (const Decl *D = getCursorDecl(cursor)) {
6154 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006155 if (!DC)
6156 return clang_getNullCursor();
6157
6158 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6159 getCursorTU(cursor));
6160 }
6161 }
6162
6163 // FIXME: Note that we can't easily compute the lexical context of a
6164 // statement or expression, so we return nothing.
6165 return clang_getNullCursor();
6166}
6167
6168CXFile clang_getIncludedFile(CXCursor cursor) {
6169 if (cursor.kind != CXCursor_InclusionDirective)
6170 return 0;
6171
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006172 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006173 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006174}
6175
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006176unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6177 if (C.kind != CXCursor_ObjCPropertyDecl)
6178 return CXObjCPropertyAttr_noattr;
6179
6180 unsigned Result = CXObjCPropertyAttr_noattr;
6181 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6182 ObjCPropertyDecl::PropertyAttributeKind Attr =
6183 PD->getPropertyAttributesAsWritten();
6184
6185#define SET_CXOBJCPROP_ATTR(A) \
6186 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6187 Result |= CXObjCPropertyAttr_##A
6188 SET_CXOBJCPROP_ATTR(readonly);
6189 SET_CXOBJCPROP_ATTR(getter);
6190 SET_CXOBJCPROP_ATTR(assign);
6191 SET_CXOBJCPROP_ATTR(readwrite);
6192 SET_CXOBJCPROP_ATTR(retain);
6193 SET_CXOBJCPROP_ATTR(copy);
6194 SET_CXOBJCPROP_ATTR(nonatomic);
6195 SET_CXOBJCPROP_ATTR(setter);
6196 SET_CXOBJCPROP_ATTR(atomic);
6197 SET_CXOBJCPROP_ATTR(weak);
6198 SET_CXOBJCPROP_ATTR(strong);
6199 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6200#undef SET_CXOBJCPROP_ATTR
6201
6202 return Result;
6203}
6204
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006205unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6206 if (!clang_isDeclaration(C.kind))
6207 return CXObjCDeclQualifier_None;
6208
6209 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6210 const Decl *D = getCursorDecl(C);
6211 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6212 QT = MD->getObjCDeclQualifier();
6213 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6214 QT = PD->getObjCDeclQualifier();
6215 if (QT == Decl::OBJC_TQ_None)
6216 return CXObjCDeclQualifier_None;
6217
6218 unsigned Result = CXObjCDeclQualifier_None;
6219 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6220 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6221 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6222 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6223 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6224 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6225
6226 return Result;
6227}
6228
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006229unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6230 if (!clang_isDeclaration(C.kind))
6231 return 0;
6232
6233 const Decl *D = getCursorDecl(C);
6234 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6235 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6236 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6237 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6238
6239 return 0;
6240}
6241
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006242unsigned clang_Cursor_isVariadic(CXCursor C) {
6243 if (!clang_isDeclaration(C.kind))
6244 return 0;
6245
6246 const Decl *D = getCursorDecl(C);
6247 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6248 return FD->isVariadic();
6249 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6250 return MD->isVariadic();
6251
6252 return 0;
6253}
6254
Guy Benyei11169dd2012-12-18 14:30:41 +00006255CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6256 if (!clang_isDeclaration(C.kind))
6257 return clang_getNullRange();
6258
6259 const Decl *D = getCursorDecl(C);
6260 ASTContext &Context = getCursorContext(C);
6261 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6262 if (!RC)
6263 return clang_getNullRange();
6264
6265 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6266}
6267
6268CXString clang_Cursor_getRawCommentText(CXCursor C) {
6269 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006270 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006271
6272 const Decl *D = getCursorDecl(C);
6273 ASTContext &Context = getCursorContext(C);
6274 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6275 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6276 StringRef();
6277
6278 // Don't duplicate the string because RawText points directly into source
6279 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006280 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006281}
6282
6283CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6284 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006285 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006286
6287 const Decl *D = getCursorDecl(C);
6288 const ASTContext &Context = getCursorContext(C);
6289 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6290
6291 if (RC) {
6292 StringRef BriefText = RC->getBriefText(Context);
6293
6294 // Don't duplicate the string because RawComment ensures that this memory
6295 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006296 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006297 }
6298
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006299 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006300}
6301
6302CXComment clang_Cursor_getParsedComment(CXCursor C) {
6303 if (!clang_isDeclaration(C.kind))
6304 return cxcomment::createCXComment(NULL, NULL);
6305
6306 const Decl *D = getCursorDecl(C);
6307 const ASTContext &Context = getCursorContext(C);
6308 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6309
6310 return cxcomment::createCXComment(FC, getCursorTU(C));
6311}
6312
6313CXModule clang_Cursor_getModule(CXCursor C) {
6314 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006315 if (const ImportDecl *ImportD =
6316 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006317 return ImportD->getImportedModule();
6318 }
6319
6320 return 0;
6321}
6322
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006323CXFile clang_Module_getASTFile(CXModule CXMod) {
6324 if (!CXMod)
6325 return 0;
6326 Module *Mod = static_cast<Module*>(CXMod);
6327 return const_cast<FileEntry *>(Mod->getASTFile());
6328}
6329
Guy Benyei11169dd2012-12-18 14:30:41 +00006330CXModule clang_Module_getParent(CXModule CXMod) {
6331 if (!CXMod)
6332 return 0;
6333 Module *Mod = static_cast<Module*>(CXMod);
6334 return Mod->Parent;
6335}
6336
6337CXString clang_Module_getName(CXModule CXMod) {
6338 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006339 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006340 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006341 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006342}
6343
6344CXString clang_Module_getFullName(CXModule CXMod) {
6345 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006346 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006347 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006348 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006349}
6350
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006351unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6352 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006353 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006354 LOG_BAD_TU(TU);
6355 return 0;
6356 }
6357 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006358 return 0;
6359 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006360 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6361 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6362 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006363}
6364
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006365CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6366 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006367 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006368 LOG_BAD_TU(TU);
6369 return 0;
6370 }
6371 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006372 return 0;
6373 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006374 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006375
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006376 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6377 if (Index < TopHeaders.size())
6378 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006379
6380 return 0;
6381}
6382
6383} // end: extern "C"
6384
6385//===----------------------------------------------------------------------===//
6386// C++ AST instrospection.
6387//===----------------------------------------------------------------------===//
6388
6389extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006390unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6391 if (!clang_isDeclaration(C.kind))
6392 return 0;
6393
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006394 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006395 const CXXMethodDecl *Method =
6396 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006397 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6398}
6399
Guy Benyei11169dd2012-12-18 14:30:41 +00006400unsigned clang_CXXMethod_isStatic(CXCursor C) {
6401 if (!clang_isDeclaration(C.kind))
6402 return 0;
6403
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006404 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006405 const CXXMethodDecl *Method =
6406 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006407 return (Method && Method->isStatic()) ? 1 : 0;
6408}
6409
6410unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6411 if (!clang_isDeclaration(C.kind))
6412 return 0;
6413
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006414 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006415 const CXXMethodDecl *Method =
6416 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006417 return (Method && Method->isVirtual()) ? 1 : 0;
6418}
6419} // end: extern "C"
6420
6421//===----------------------------------------------------------------------===//
6422// Attribute introspection.
6423//===----------------------------------------------------------------------===//
6424
6425extern "C" {
6426CXType clang_getIBOutletCollectionType(CXCursor C) {
6427 if (C.kind != CXCursor_IBOutletCollectionAttr)
6428 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6429
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006430 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006431 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6432
6433 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6434}
6435} // end: extern "C"
6436
6437//===----------------------------------------------------------------------===//
6438// Inspecting memory usage.
6439//===----------------------------------------------------------------------===//
6440
6441typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6442
6443static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6444 enum CXTUResourceUsageKind k,
6445 unsigned long amount) {
6446 CXTUResourceUsageEntry entry = { k, amount };
6447 entries.push_back(entry);
6448}
6449
6450extern "C" {
6451
6452const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6453 const char *str = "";
6454 switch (kind) {
6455 case CXTUResourceUsage_AST:
6456 str = "ASTContext: expressions, declarations, and types";
6457 break;
6458 case CXTUResourceUsage_Identifiers:
6459 str = "ASTContext: identifiers";
6460 break;
6461 case CXTUResourceUsage_Selectors:
6462 str = "ASTContext: selectors";
6463 break;
6464 case CXTUResourceUsage_GlobalCompletionResults:
6465 str = "Code completion: cached global results";
6466 break;
6467 case CXTUResourceUsage_SourceManagerContentCache:
6468 str = "SourceManager: content cache allocator";
6469 break;
6470 case CXTUResourceUsage_AST_SideTables:
6471 str = "ASTContext: side tables";
6472 break;
6473 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6474 str = "SourceManager: malloc'ed memory buffers";
6475 break;
6476 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6477 str = "SourceManager: mmap'ed memory buffers";
6478 break;
6479 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6480 str = "ExternalASTSource: malloc'ed memory buffers";
6481 break;
6482 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6483 str = "ExternalASTSource: mmap'ed memory buffers";
6484 break;
6485 case CXTUResourceUsage_Preprocessor:
6486 str = "Preprocessor: malloc'ed memory";
6487 break;
6488 case CXTUResourceUsage_PreprocessingRecord:
6489 str = "Preprocessor: PreprocessingRecord";
6490 break;
6491 case CXTUResourceUsage_SourceManager_DataStructures:
6492 str = "SourceManager: data structures and tables";
6493 break;
6494 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6495 str = "Preprocessor: header search tables";
6496 break;
6497 }
6498 return str;
6499}
6500
6501CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006502 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006503 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006504 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6505 return usage;
6506 }
6507
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006508 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006509 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006510 ASTContext &astContext = astUnit->getASTContext();
6511
6512 // How much memory is used by AST nodes and types?
6513 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6514 (unsigned long) astContext.getASTAllocatedMemory());
6515
6516 // How much memory is used by identifiers?
6517 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6518 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6519
6520 // How much memory is used for selectors?
6521 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6522 (unsigned long) astContext.Selectors.getTotalMemory());
6523
6524 // How much memory is used by ASTContext's side tables?
6525 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6526 (unsigned long) astContext.getSideTableAllocatedMemory());
6527
6528 // How much memory is used for caching global code completion results?
6529 unsigned long completionBytes = 0;
6530 if (GlobalCodeCompletionAllocator *completionAllocator =
6531 astUnit->getCachedCompletionAllocator().getPtr()) {
6532 completionBytes = completionAllocator->getTotalMemory();
6533 }
6534 createCXTUResourceUsageEntry(*entries,
6535 CXTUResourceUsage_GlobalCompletionResults,
6536 completionBytes);
6537
6538 // How much memory is being used by SourceManager's content cache?
6539 createCXTUResourceUsageEntry(*entries,
6540 CXTUResourceUsage_SourceManagerContentCache,
6541 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6542
6543 // How much memory is being used by the MemoryBuffer's in SourceManager?
6544 const SourceManager::MemoryBufferSizes &srcBufs =
6545 astUnit->getSourceManager().getMemoryBufferSizes();
6546
6547 createCXTUResourceUsageEntry(*entries,
6548 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6549 (unsigned long) srcBufs.malloc_bytes);
6550 createCXTUResourceUsageEntry(*entries,
6551 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6552 (unsigned long) srcBufs.mmap_bytes);
6553 createCXTUResourceUsageEntry(*entries,
6554 CXTUResourceUsage_SourceManager_DataStructures,
6555 (unsigned long) astContext.getSourceManager()
6556 .getDataStructureSizes());
6557
6558 // How much memory is being used by the ExternalASTSource?
6559 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6560 const ExternalASTSource::MemoryBufferSizes &sizes =
6561 esrc->getMemoryBufferSizes();
6562
6563 createCXTUResourceUsageEntry(*entries,
6564 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6565 (unsigned long) sizes.malloc_bytes);
6566 createCXTUResourceUsageEntry(*entries,
6567 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6568 (unsigned long) sizes.mmap_bytes);
6569 }
6570
6571 // How much memory is being used by the Preprocessor?
6572 Preprocessor &pp = astUnit->getPreprocessor();
6573 createCXTUResourceUsageEntry(*entries,
6574 CXTUResourceUsage_Preprocessor,
6575 pp.getTotalMemory());
6576
6577 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6578 createCXTUResourceUsageEntry(*entries,
6579 CXTUResourceUsage_PreprocessingRecord,
6580 pRec->getTotalMemory());
6581 }
6582
6583 createCXTUResourceUsageEntry(*entries,
6584 CXTUResourceUsage_Preprocessor_HeaderSearch,
6585 pp.getHeaderSearchInfo().getTotalMemory());
6586
6587 CXTUResourceUsage usage = { (void*) entries.get(),
6588 (unsigned) entries->size(),
6589 entries->size() ? &(*entries)[0] : 0 };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006590 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006591 return usage;
6592}
6593
6594void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6595 if (usage.data)
6596 delete (MemUsageEntries*) usage.data;
6597}
6598
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006599CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6600 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006601 skipped->count = 0;
6602 skipped->ranges = 0;
6603
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006604 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006605 LOG_BAD_TU(TU);
6606 return skipped;
6607 }
6608
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006609 if (!file)
6610 return skipped;
6611
6612 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6613 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6614 if (!ppRec)
6615 return skipped;
6616
6617 ASTContext &Ctx = astUnit->getASTContext();
6618 SourceManager &sm = Ctx.getSourceManager();
6619 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6620 FileID wantedFileID = sm.translateFile(fileEntry);
6621
6622 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6623 std::vector<SourceRange> wantedRanges;
6624 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6625 i != ei; ++i) {
6626 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6627 wantedRanges.push_back(*i);
6628 }
6629
6630 skipped->count = wantedRanges.size();
6631 skipped->ranges = new CXSourceRange[skipped->count];
6632 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6633 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6634
6635 return skipped;
6636}
6637
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006638void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6639 if (ranges) {
6640 delete[] ranges->ranges;
6641 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006642 }
6643}
6644
Guy Benyei11169dd2012-12-18 14:30:41 +00006645} // end extern "C"
6646
6647void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6648 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6649 for (unsigned I = 0; I != Usage.numEntries; ++I)
6650 fprintf(stderr, " %s: %lu\n",
6651 clang_getTUResourceUsageName(Usage.entries[I].kind),
6652 Usage.entries[I].amount);
6653
6654 clang_disposeCXTUResourceUsage(Usage);
6655}
6656
6657//===----------------------------------------------------------------------===//
6658// Misc. utility functions.
6659//===----------------------------------------------------------------------===//
6660
6661/// Default to using an 8 MB stack size on "safety" threads.
6662static unsigned SafetyStackThreadSize = 8 << 20;
6663
6664namespace clang {
6665
6666bool RunSafely(llvm::CrashRecoveryContext &CRC,
6667 void (*Fn)(void*), void *UserData,
6668 unsigned Size) {
6669 if (!Size)
6670 Size = GetSafetyThreadStackSize();
6671 if (Size)
6672 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6673 return CRC.RunSafely(Fn, UserData);
6674}
6675
6676unsigned GetSafetyThreadStackSize() {
6677 return SafetyStackThreadSize;
6678}
6679
6680void SetSafetyThreadStackSize(unsigned Value) {
6681 SafetyStackThreadSize = Value;
6682}
6683
6684}
6685
6686void clang::setThreadBackgroundPriority() {
6687 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6688 return;
6689
6690 // FIXME: Move to llvm/Support and make it cross-platform.
6691#ifdef __APPLE__
6692 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6693#endif
6694}
6695
6696void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6697 if (!Unit)
6698 return;
6699
6700 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6701 DEnd = Unit->stored_diag_end();
6702 D != DEnd; ++D) {
6703 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6704 CXString Msg = clang_formatDiagnostic(&Diag,
6705 clang_defaultDiagnosticDisplayOptions());
6706 fprintf(stderr, "%s\n", clang_getCString(Msg));
6707 clang_disposeString(Msg);
6708 }
6709#ifdef LLVM_ON_WIN32
6710 // On Windows, force a flush, since there may be multiple copies of
6711 // stderr and stdout in the file system, all with different buffers
6712 // but writing to the same device.
6713 fflush(stderr);
6714#endif
6715}
6716
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006717MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6718 SourceLocation MacroDefLoc,
6719 CXTranslationUnit TU){
6720 if (MacroDefLoc.isInvalid() || !TU)
6721 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006722 if (!II.hadMacroDefinition())
6723 return 0;
6724
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006725 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006726 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006727 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006728 if (MD) {
6729 for (MacroDirective::DefInfo
6730 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6731 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6732 return Def.getMacroInfo();
6733 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006734 }
6735
6736 return 0;
6737}
6738
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006739const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6740 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006741 if (!MacroDef || !TU)
6742 return 0;
6743 const IdentifierInfo *II = MacroDef->getName();
6744 if (!II)
6745 return 0;
6746
6747 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6748}
6749
6750MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6751 const Token &Tok,
6752 CXTranslationUnit TU) {
6753 if (!MI || !TU)
6754 return 0;
6755 if (Tok.isNot(tok::raw_identifier))
6756 return 0;
6757
6758 if (MI->getNumTokens() == 0)
6759 return 0;
6760 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6761 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006762 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006763
6764 // Check that the token is inside the definition and not its argument list.
6765 SourceManager &SM = Unit->getSourceManager();
6766 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6767 return 0;
6768 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6769 return 0;
6770
6771 Preprocessor &PP = Unit->getPreprocessor();
6772 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6773 if (!PPRec)
6774 return 0;
6775
6776 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6777 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6778 if (!II.hadMacroDefinition())
6779 return 0;
6780
6781 // Check that the identifier is not one of the macro arguments.
6782 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6783 return 0;
6784
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006785 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6786 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006787 return 0;
6788
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006789 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006790}
6791
6792MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6793 SourceLocation Loc,
6794 CXTranslationUnit TU) {
6795 if (Loc.isInvalid() || !MI || !TU)
6796 return 0;
6797
6798 if (MI->getNumTokens() == 0)
6799 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006800 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006801 Preprocessor &PP = Unit->getPreprocessor();
6802 if (!PP.getPreprocessingRecord())
6803 return 0;
6804 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6805 Token Tok;
6806 if (PP.getRawToken(Loc, Tok))
6807 return 0;
6808
6809 return checkForMacroInMacroDefinition(MI, Tok, TU);
6810}
6811
Guy Benyei11169dd2012-12-18 14:30:41 +00006812extern "C" {
6813
6814CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006815 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006816}
6817
6818} // end: extern "C"
6819
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006820Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6821 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006822 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006823 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006824 if (Unit->isMainFileAST())
6825 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006826 return *this;
6827 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006828 } else {
6829 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006830 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006831 return *this;
6832}
6833
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006834Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6835 *this << FE->getName();
6836 return *this;
6837}
6838
6839Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6840 CXString cursorName = clang_getCursorDisplayName(cursor);
6841 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6842 clang_disposeString(cursorName);
6843 return *this;
6844}
6845
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006846Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6847 CXFile File;
6848 unsigned Line, Column;
6849 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6850 CXString FileName = clang_getFileName(File);
6851 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6852 clang_disposeString(FileName);
6853 return *this;
6854}
6855
6856Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6857 CXSourceLocation BLoc = clang_getRangeStart(range);
6858 CXSourceLocation ELoc = clang_getRangeEnd(range);
6859
6860 CXFile BFile;
6861 unsigned BLine, BColumn;
6862 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6863
6864 CXFile EFile;
6865 unsigned ELine, EColumn;
6866 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6867
6868 CXString BFileName = clang_getFileName(BFile);
6869 if (BFile == EFile) {
6870 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6871 BLine, BColumn, ELine, EColumn);
6872 } else {
6873 CXString EFileName = clang_getFileName(EFile);
6874 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6875 BLine, BColumn)
6876 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6877 ELine, EColumn);
6878 clang_disposeString(EFileName);
6879 }
6880 clang_disposeString(BFileName);
6881 return *this;
6882}
6883
6884Logger &cxindex::Logger::operator<<(CXString Str) {
6885 *this << clang_getCString(Str);
6886 return *this;
6887}
6888
6889Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6890 LogOS << Fmt;
6891 return *this;
6892}
6893
6894cxindex::Logger::~Logger() {
6895 LogOS.flush();
6896
6897 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6898
6899 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6900
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006901 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006902 OS << "[libclang:" << Name << ':';
6903
6904 // FIXME: Portability.
6905#if HAVE_PTHREAD_H && __APPLE__
6906 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6907 OS << tid << ':';
6908#endif
6909
6910 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6911 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6912 OS << Msg.str() << '\n';
6913
6914 if (Trace) {
6915 llvm::sys::PrintStackTrace(stderr);
6916 OS << "--------------------------------------------------\n";
6917 }
6918}