blob: 255e642b15ded56a3c9bbb04f6f314789da0e3da [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;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002075 for (const auto *D : S->decls()) {
2076 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002077 isFirst = false;
2078 }
2079 if (size == WL.size())
2080 return;
2081 // Now reverse the entries we just added. This will match the DFS
2082 // ordering performed by the worklist.
2083 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2084 std::reverse(I, E);
2085}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002086void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002087 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002088 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002089 D = E->designators_rbegin(), DEnd = E->designators_rend();
2090 D != DEnd; ++D) {
2091 if (D->isFieldDesignator()) {
2092 if (FieldDecl *Field = D->getField())
2093 AddMemberRef(Field, D->getFieldLoc());
2094 continue;
2095 }
2096 if (D->isArrayDesignator()) {
2097 AddStmt(E->getArrayIndex(*D));
2098 continue;
2099 }
2100 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2101 AddStmt(E->getArrayRangeEnd(*D));
2102 AddStmt(E->getArrayRangeStart(*D));
2103 }
2104}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002105void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002106 EnqueueChildren(E);
2107 AddTypeLoc(E->getTypeInfoAsWritten());
2108}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002109void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002110 AddStmt(FS->getBody());
2111 AddStmt(FS->getInc());
2112 AddStmt(FS->getCond());
2113 AddDecl(FS->getConditionVariable());
2114 AddStmt(FS->getInit());
2115}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002116void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002117 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2118}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002119void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002120 AddStmt(If->getElse());
2121 AddStmt(If->getThen());
2122 AddStmt(If->getCond());
2123 AddDecl(If->getConditionVariable());
2124}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002125void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002126 // We care about the syntactic form of the initializer list, only.
2127 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2128 IE = Syntactic;
2129 EnqueueChildren(IE);
2130}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002131void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002132 WL.push_back(MemberExprParts(M, Parent));
2133
2134 // If the base of the member access expression is an implicit 'this', don't
2135 // visit it.
2136 // FIXME: If we ever want to show these implicit accesses, this will be
2137 // unfortunate. However, clang_getCursor() relies on this behavior.
2138 if (!M->isImplicitAccess())
2139 AddStmt(M->getBase());
2140}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002141void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002142 AddTypeLoc(E->getEncodedTypeSourceInfo());
2143}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002144void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002145 EnqueueChildren(M);
2146 AddTypeLoc(M->getClassReceiverTypeInfo());
2147}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002148void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002149 // Visit the components of the offsetof expression.
2150 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2151 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2152 const OffsetOfNode &Node = E->getComponent(I-1);
2153 switch (Node.getKind()) {
2154 case OffsetOfNode::Array:
2155 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2156 break;
2157 case OffsetOfNode::Field:
2158 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2159 break;
2160 case OffsetOfNode::Identifier:
2161 case OffsetOfNode::Base:
2162 continue;
2163 }
2164 }
2165 // Visit the type into which we're computing the offset.
2166 AddTypeLoc(E->getTypeSourceInfo());
2167}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002168void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002169 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2170 WL.push_back(OverloadExprParts(E, Parent));
2171}
2172void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002173 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002174 EnqueueChildren(E);
2175 if (E->isArgumentType())
2176 AddTypeLoc(E->getArgumentTypeInfo());
2177}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002178void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002179 EnqueueChildren(S);
2180}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002181void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002182 AddStmt(S->getBody());
2183 AddStmt(S->getCond());
2184 AddDecl(S->getConditionVariable());
2185}
2186
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002187void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002188 AddStmt(W->getBody());
2189 AddStmt(W->getCond());
2190 AddDecl(W->getConditionVariable());
2191}
2192
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002193void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002194 for (unsigned I = E->getNumArgs(); I > 0; --I)
2195 AddTypeLoc(E->getArg(I-1));
2196}
2197
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002198void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002199 AddTypeLoc(E->getQueriedTypeSourceInfo());
2200}
2201
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002202void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002203 EnqueueChildren(E);
2204}
2205
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002206void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002207 VisitOverloadExpr(U);
2208 if (!U->isImplicitAccess())
2209 AddStmt(U->getBase());
2210}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002212 AddStmt(E->getSubExpr());
2213 AddTypeLoc(E->getWrittenTypeInfo());
2214}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002215void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002216 WL.push_back(SizeOfPackExprParts(E, Parent));
2217}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 // If the opaque value has a source expression, just transparently
2220 // visit that. This is useful for (e.g.) pseudo-object expressions.
2221 if (Expr *SourceExpr = E->getSourceExpr())
2222 return Visit(SourceExpr);
2223}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002224void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002225 AddStmt(E->getBody());
2226 WL.push_back(LambdaExprParts(E, Parent));
2227}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002228void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002229 // Treat the expression like its syntactic form.
2230 Visit(E->getSyntacticForm());
2231}
2232
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002233void EnqueueVisitor::VisitOMPExecutableDirective(
2234 const OMPExecutableDirective *D) {
2235 EnqueueChildren(D);
2236 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2237 E = D->clauses().end();
2238 I != E; ++I)
2239 EnqueueChildren(*I);
2240}
2241
2242void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2243 VisitOMPExecutableDirective(D);
2244}
2245
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002246void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2247 VisitOMPExecutableDirective(D);
2248}
2249
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002250void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002251 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2252}
2253
2254bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2255 if (RegionOfInterest.isValid()) {
2256 SourceRange Range = getRawCursorExtent(C);
2257 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2258 return false;
2259 }
2260 return true;
2261}
2262
2263bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2264 while (!WL.empty()) {
2265 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002266 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002267
2268 // Set the Parent field, then back to its old value once we're done.
2269 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2270
2271 switch (LI.getKind()) {
2272 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002273 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002274 if (!D)
2275 continue;
2276
2277 // For now, perform default visitation for Decls.
2278 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2279 cast<DeclVisit>(&LI)->isFirst())))
2280 return true;
2281
2282 continue;
2283 }
2284 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2285 const ASTTemplateArgumentListInfo *ArgList =
2286 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2287 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2288 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2289 Arg != ArgEnd; ++Arg) {
2290 if (VisitTemplateArgumentLoc(*Arg))
2291 return true;
2292 }
2293 continue;
2294 }
2295 case VisitorJob::TypeLocVisitKind: {
2296 // Perform default visitation for TypeLocs.
2297 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2298 return true;
2299 continue;
2300 }
2301 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002302 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002303 if (LabelStmt *stmt = LS->getStmt()) {
2304 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2305 TU))) {
2306 return true;
2307 }
2308 }
2309 continue;
2310 }
2311
2312 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2313 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2314 if (VisitNestedNameSpecifierLoc(V->get()))
2315 return true;
2316 continue;
2317 }
2318
2319 case VisitorJob::DeclarationNameInfoVisitKind: {
2320 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2321 ->get()))
2322 return true;
2323 continue;
2324 }
2325 case VisitorJob::MemberRefVisitKind: {
2326 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2327 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2328 return true;
2329 continue;
2330 }
2331 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002332 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002333 if (!S)
2334 continue;
2335
2336 // Update the current cursor.
2337 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2338 if (!IsInRegionOfInterest(Cursor))
2339 continue;
2340 switch (Visitor(Cursor, Parent, ClientData)) {
2341 case CXChildVisit_Break: return true;
2342 case CXChildVisit_Continue: break;
2343 case CXChildVisit_Recurse:
2344 if (PostChildrenVisitor)
2345 WL.push_back(PostChildrenVisit(0, Cursor));
2346 EnqueueWorkList(WL, S);
2347 break;
2348 }
2349 continue;
2350 }
2351 case VisitorJob::MemberExprPartsKind: {
2352 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002353 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002354
2355 // Visit the nested-name-specifier
2356 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2357 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2358 return true;
2359
2360 // Visit the declaration name.
2361 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2362 return true;
2363
2364 // Visit the explicitly-specified template arguments, if any.
2365 if (M->hasExplicitTemplateArgs()) {
2366 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2367 *ArgEnd = Arg + M->getNumTemplateArgs();
2368 Arg != ArgEnd; ++Arg) {
2369 if (VisitTemplateArgumentLoc(*Arg))
2370 return true;
2371 }
2372 }
2373 continue;
2374 }
2375 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002376 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002377 // Visit nested-name-specifier, if present.
2378 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2379 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2380 return true;
2381 // Visit declaration name.
2382 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2383 return true;
2384 continue;
2385 }
2386 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002387 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002388 // Visit the nested-name-specifier.
2389 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2390 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2391 return true;
2392 // Visit the declaration name.
2393 if (VisitDeclarationNameInfo(O->getNameInfo()))
2394 return true;
2395 // Visit the overloaded declaration reference.
2396 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2397 return true;
2398 continue;
2399 }
2400 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002401 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002402 NamedDecl *Pack = E->getPack();
2403 if (isa<TemplateTypeParmDecl>(Pack)) {
2404 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2405 E->getPackLoc(), TU)))
2406 return true;
2407
2408 continue;
2409 }
2410
2411 if (isa<TemplateTemplateParmDecl>(Pack)) {
2412 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2413 E->getPackLoc(), TU)))
2414 return true;
2415
2416 continue;
2417 }
2418
2419 // Non-type template parameter packs and function parameter packs are
2420 // treated like DeclRefExpr cursors.
2421 continue;
2422 }
2423
2424 case VisitorJob::LambdaExprPartsKind: {
2425 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002426 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002427 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2428 CEnd = E->explicit_capture_end();
2429 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002430 // FIXME: Lambda init-captures.
2431 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002432 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002433
Guy Benyei11169dd2012-12-18 14:30:41 +00002434 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2435 C->getLocation(),
2436 TU)))
2437 return true;
2438 }
2439
2440 // Visit parameters and return type, if present.
2441 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2442 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2443 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2444 // Visit the whole type.
2445 if (Visit(TL))
2446 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002447 } else if (FunctionProtoTypeLoc Proto =
2448 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002449 if (E->hasExplicitParameters()) {
2450 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002451 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2452 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002453 return true;
2454 } else {
2455 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002456 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002457 return true;
2458 }
2459 }
2460 }
2461 break;
2462 }
2463
2464 case VisitorJob::PostChildrenVisitKind:
2465 if (PostChildrenVisitor(Parent, ClientData))
2466 return true;
2467 break;
2468 }
2469 }
2470 return false;
2471}
2472
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002473bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002474 VisitorWorkList *WL = 0;
2475 if (!WorkListFreeList.empty()) {
2476 WL = WorkListFreeList.back();
2477 WL->clear();
2478 WorkListFreeList.pop_back();
2479 }
2480 else {
2481 WL = new VisitorWorkList();
2482 WorkListCache.push_back(WL);
2483 }
2484 EnqueueWorkList(*WL, S);
2485 bool result = RunVisitorWorkList(*WL);
2486 WorkListFreeList.push_back(WL);
2487 return result;
2488}
2489
2490namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002491typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002492RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2493 const DeclarationNameInfo &NI,
2494 const SourceRange &QLoc,
2495 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2496 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2497 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2498 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2499
2500 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2501
2502 RefNamePieces Pieces;
2503
2504 if (WantQualifier && QLoc.isValid())
2505 Pieces.push_back(QLoc);
2506
2507 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2508 Pieces.push_back(NI.getLoc());
2509
2510 if (WantTemplateArgs && TemplateArgs)
2511 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2512 TemplateArgs->RAngleLoc));
2513
2514 if (Kind == DeclarationName::CXXOperatorName) {
2515 Pieces.push_back(SourceLocation::getFromRawEncoding(
2516 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2517 Pieces.push_back(SourceLocation::getFromRawEncoding(
2518 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2519 }
2520
2521 if (WantSinglePiece) {
2522 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2523 Pieces.clear();
2524 Pieces.push_back(R);
2525 }
2526
2527 return Pieces;
2528}
2529}
2530
2531//===----------------------------------------------------------------------===//
2532// Misc. API hooks.
2533//===----------------------------------------------------------------------===//
2534
2535static llvm::sys::Mutex EnableMultithreadingMutex;
2536static bool EnabledMultithreading;
2537
Chad Rosier05c71aa2013-03-27 18:28:23 +00002538static void fatal_error_handler(void *user_data, const std::string& reason,
2539 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002540 // Write the result out to stderr avoiding errs() because raw_ostreams can
2541 // call report_fatal_error.
2542 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2543 ::abort();
2544}
2545
2546extern "C" {
2547CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2548 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002549 // We use crash recovery to make some of our APIs more reliable, implicitly
2550 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002551 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2552 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002553
2554 // Enable support for multithreading in LLVM.
2555 {
2556 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2557 if (!EnabledMultithreading) {
2558 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2559 llvm::llvm_start_multithreaded();
2560 EnabledMultithreading = true;
2561 }
2562 }
2563
2564 CIndexer *CIdxr = new CIndexer();
2565 if (excludeDeclarationsFromPCH)
2566 CIdxr->setOnlyLocalDecls();
2567 if (displayDiagnostics)
2568 CIdxr->setDisplayDiagnostics();
2569
2570 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2571 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2572 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2573 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2574 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2575 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2576
2577 return CIdxr;
2578}
2579
2580void clang_disposeIndex(CXIndex CIdx) {
2581 if (CIdx)
2582 delete static_cast<CIndexer *>(CIdx);
2583}
2584
2585void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2586 if (CIdx)
2587 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2588}
2589
2590unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2591 if (CIdx)
2592 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2593 return 0;
2594}
2595
2596void clang_toggleCrashRecovery(unsigned isEnabled) {
2597 if (isEnabled)
2598 llvm::CrashRecoveryContext::Enable();
2599 else
2600 llvm::CrashRecoveryContext::Disable();
2601}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002602
Guy Benyei11169dd2012-12-18 14:30:41 +00002603CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2604 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002605 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002606 enum CXErrorCode Result =
2607 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002608 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002609 assert((TU && Result == CXError_Success) ||
2610 (!TU && Result != CXError_Success));
2611 return TU;
2612}
2613
2614enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2615 const char *ast_filename,
2616 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002617 if (out_TU)
2618 *out_TU = NULL;
2619
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002620 if (!CIdx || !ast_filename || !out_TU)
2621 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002622
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002623 LOG_FUNC_SECTION {
2624 *Log << ast_filename;
2625 }
2626
Guy Benyei11169dd2012-12-18 14:30:41 +00002627 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2628 FileSystemOptions FileSystemOpts;
2629
2630 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002631 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002632 CXXIdx->getOnlyLocalDecls(), None,
2633 /*CaptureDiagnostics=*/true,
2634 /*AllowPCHWithCompilerErrors=*/true,
2635 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002636 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2637 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002638}
2639
2640unsigned clang_defaultEditingTranslationUnitOptions() {
2641 return CXTranslationUnit_PrecompiledPreamble |
2642 CXTranslationUnit_CacheCompletionResults;
2643}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002644
Guy Benyei11169dd2012-12-18 14:30:41 +00002645CXTranslationUnit
2646clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2647 const char *source_filename,
2648 int num_command_line_args,
2649 const char * const *command_line_args,
2650 unsigned num_unsaved_files,
2651 struct CXUnsavedFile *unsaved_files) {
2652 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2653 return clang_parseTranslationUnit(CIdx, source_filename,
2654 command_line_args, num_command_line_args,
2655 unsaved_files, num_unsaved_files,
2656 Options);
2657}
2658
2659struct ParseTranslationUnitInfo {
2660 CXIndex CIdx;
2661 const char *source_filename;
2662 const char *const *command_line_args;
2663 int num_command_line_args;
2664 struct CXUnsavedFile *unsaved_files;
2665 unsigned num_unsaved_files;
2666 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002667 CXTranslationUnit *out_TU;
2668 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002669};
2670static void clang_parseTranslationUnit_Impl(void *UserData) {
2671 ParseTranslationUnitInfo *PTUI =
2672 static_cast<ParseTranslationUnitInfo*>(UserData);
2673 CXIndex CIdx = PTUI->CIdx;
2674 const char *source_filename = PTUI->source_filename;
2675 const char * const *command_line_args = PTUI->command_line_args;
2676 int num_command_line_args = PTUI->num_command_line_args;
2677 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2678 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2679 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002680 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002681
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002682 // Set up the initial return values.
2683 if (out_TU)
2684 *out_TU = NULL;
2685 PTUI->result = CXError_Failure;
2686
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002687 // Check arguments.
2688 if (!CIdx || !out_TU ||
2689 (unsaved_files == NULL && num_unsaved_files != 0)) {
2690 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002691 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002692 }
2693
Guy Benyei11169dd2012-12-18 14:30:41 +00002694 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2695
2696 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2697 setThreadBackgroundPriority();
2698
2699 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2700 // FIXME: Add a flag for modules.
2701 TranslationUnitKind TUKind
2702 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002703 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002704 = options & CXTranslationUnit_CacheCompletionResults;
2705 bool IncludeBriefCommentsInCodeCompletion
2706 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2707 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2708 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2709
2710 // Configure the diagnostics.
2711 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002712 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002713
2714 // Recover resources if we crash before exiting this function.
2715 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2716 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2717 DiagCleanup(Diags.getPtr());
2718
Ahmed Charlesb8984322014-03-07 20:03:18 +00002719 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2720 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002721
2722 // Recover resources if we crash before exiting this function.
2723 llvm::CrashRecoveryContextCleanupRegistrar<
2724 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2725
2726 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2727 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2728 const llvm::MemoryBuffer *Buffer
2729 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2730 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2731 Buffer));
2732 }
2733
Ahmed Charlesb8984322014-03-07 20:03:18 +00002734 std::unique_ptr<std::vector<const char *>> Args(
2735 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002736
2737 // Recover resources if we crash before exiting this method.
2738 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2739 ArgsCleanup(Args.get());
2740
2741 // Since the Clang C library is primarily used by batch tools dealing with
2742 // (often very broken) source code, where spell-checking can have a
2743 // significant negative impact on performance (particularly when
2744 // precompiled headers are involved), we disable it by default.
2745 // Only do this if we haven't found a spell-checking-related argument.
2746 bool FoundSpellCheckingArgument = false;
2747 for (int I = 0; I != num_command_line_args; ++I) {
2748 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2749 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2750 FoundSpellCheckingArgument = true;
2751 break;
2752 }
2753 }
2754 if (!FoundSpellCheckingArgument)
2755 Args->push_back("-fno-spell-checking");
2756
2757 Args->insert(Args->end(), command_line_args,
2758 command_line_args + num_command_line_args);
2759
2760 // The 'source_filename' argument is optional. If the caller does not
2761 // specify it then it is assumed that the source file is specified
2762 // in the actual argument list.
2763 // Put the source file after command_line_args otherwise if '-x' flag is
2764 // present it will be unused.
2765 if (source_filename)
2766 Args->push_back(source_filename);
2767
2768 // Do we need the detailed preprocessing record?
2769 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2770 Args->push_back("-Xclang");
2771 Args->push_back("-detailed-preprocessing-record");
2772 }
2773
2774 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002775 std::unique_ptr<ASTUnit> ErrUnit;
2776 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002777 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002778 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2779 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2780 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2781 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2782 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2783 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002784
2785 if (NumErrors != Diags->getClient()->getNumErrors()) {
2786 // Make sure to check that 'Unit' is non-NULL.
2787 if (CXXIdx->getDisplayDiagnostics())
2788 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2789 }
2790
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002791 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2792 PTUI->result = CXError_ASTReadError;
2793 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002794 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002795 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2796 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002797}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002798
2799CXTranslationUnit
2800clang_parseTranslationUnit(CXIndex CIdx,
2801 const char *source_filename,
2802 const char *const *command_line_args,
2803 int num_command_line_args,
2804 struct CXUnsavedFile *unsaved_files,
2805 unsigned num_unsaved_files,
2806 unsigned options) {
2807 CXTranslationUnit TU;
2808 enum CXErrorCode Result = clang_parseTranslationUnit2(
2809 CIdx, source_filename, command_line_args, num_command_line_args,
2810 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002811 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002812 assert((TU && Result == CXError_Success) ||
2813 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002814 return TU;
2815}
2816
2817enum CXErrorCode clang_parseTranslationUnit2(
2818 CXIndex CIdx,
2819 const char *source_filename,
2820 const char *const *command_line_args,
2821 int num_command_line_args,
2822 struct CXUnsavedFile *unsaved_files,
2823 unsigned num_unsaved_files,
2824 unsigned options,
2825 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002826 LOG_FUNC_SECTION {
2827 *Log << source_filename << ": ";
2828 for (int i = 0; i != num_command_line_args; ++i)
2829 *Log << command_line_args[i] << " ";
2830 }
2831
Guy Benyei11169dd2012-12-18 14:30:41 +00002832 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2833 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002834 num_unsaved_files, options, out_TU,
2835 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002836 llvm::CrashRecoveryContext CRC;
2837
2838 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2839 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2840 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2841 fprintf(stderr, " 'command_line_args' : [");
2842 for (int i = 0; i != num_command_line_args; ++i) {
2843 if (i)
2844 fprintf(stderr, ", ");
2845 fprintf(stderr, "'%s'", command_line_args[i]);
2846 }
2847 fprintf(stderr, "],\n");
2848 fprintf(stderr, " 'unsaved_files' : [");
2849 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2850 if (i)
2851 fprintf(stderr, ", ");
2852 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2853 unsaved_files[i].Length);
2854 }
2855 fprintf(stderr, "],\n");
2856 fprintf(stderr, " 'options' : %d,\n", options);
2857 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002858
2859 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002860 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002861 if (CXTranslationUnit *TU = PTUI.out_TU)
2862 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002863 }
2864
2865 return PTUI.result;
2866}
2867
2868unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2869 return CXSaveTranslationUnit_None;
2870}
2871
2872namespace {
2873
2874struct SaveTranslationUnitInfo {
2875 CXTranslationUnit TU;
2876 const char *FileName;
2877 unsigned options;
2878 CXSaveError result;
2879};
2880
2881}
2882
2883static void clang_saveTranslationUnit_Impl(void *UserData) {
2884 SaveTranslationUnitInfo *STUI =
2885 static_cast<SaveTranslationUnitInfo*>(UserData);
2886
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002887 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002888 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2889 setThreadBackgroundPriority();
2890
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002891 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002892 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2893}
2894
2895int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2896 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002897 LOG_FUNC_SECTION {
2898 *Log << TU << ' ' << FileName;
2899 }
2900
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002901 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002902 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002903 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002904 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002905
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002906 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002907 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2908 if (!CXXUnit->hasSema())
2909 return CXSaveError_InvalidTU;
2910
2911 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2912
2913 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2914 getenv("LIBCLANG_NOTHREADS")) {
2915 clang_saveTranslationUnit_Impl(&STUI);
2916
2917 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2918 PrintLibclangResourceUsage(TU);
2919
2920 return STUI.result;
2921 }
2922
2923 // We have an AST that has invalid nodes due to compiler errors.
2924 // Use a crash recovery thread for protection.
2925
2926 llvm::CrashRecoveryContext CRC;
2927
2928 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2929 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2930 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2931 fprintf(stderr, " 'options' : %d,\n", options);
2932 fprintf(stderr, "}\n");
2933
2934 return CXSaveError_Unknown;
2935
2936 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2937 PrintLibclangResourceUsage(TU);
2938 }
2939
2940 return STUI.result;
2941}
2942
2943void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2944 if (CTUnit) {
2945 // If the translation unit has been marked as unsafe to free, just discard
2946 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002947 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2948 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002949 return;
2950
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002951 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002952 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002953 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2954 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002955 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002956 delete CTUnit;
2957 }
2958}
2959
2960unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2961 return CXReparse_None;
2962}
2963
2964struct ReparseTranslationUnitInfo {
2965 CXTranslationUnit TU;
2966 unsigned num_unsaved_files;
2967 struct CXUnsavedFile *unsaved_files;
2968 unsigned options;
2969 int result;
2970};
2971
2972static void clang_reparseTranslationUnit_Impl(void *UserData) {
2973 ReparseTranslationUnitInfo *RTUI =
2974 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002975 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002976
Guy Benyei11169dd2012-12-18 14:30:41 +00002977 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002978 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2979 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2980 unsigned options = RTUI->options;
2981 (void) options;
2982
2983 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002984 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002985 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002986 RTUI->result = CXError_InvalidArguments;
2987 return;
2988 }
2989 if (unsaved_files == NULL && num_unsaved_files != 0) {
2990 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00002991 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002992 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002993
2994 // Reset the associated diagnostics.
2995 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2996 TU->Diagnostics = 0;
2997
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002998 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002999 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3000 setThreadBackgroundPriority();
3001
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003002 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003003 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003004
3005 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3006 new std::vector<ASTUnit::RemappedFile>());
3007
Guy Benyei11169dd2012-12-18 14:30:41 +00003008 // Recover resources if we crash before exiting this function.
3009 llvm::CrashRecoveryContextCleanupRegistrar<
3010 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3011
3012 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3013 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3014 const llvm::MemoryBuffer *Buffer
3015 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3016 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3017 Buffer));
3018 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003019
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003020 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003021 RTUI->result = CXError_Success;
3022 else if (isASTReadError(CXXUnit))
3023 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003024}
3025
3026int clang_reparseTranslationUnit(CXTranslationUnit TU,
3027 unsigned num_unsaved_files,
3028 struct CXUnsavedFile *unsaved_files,
3029 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003030 LOG_FUNC_SECTION {
3031 *Log << TU;
3032 }
3033
Guy Benyei11169dd2012-12-18 14:30:41 +00003034 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003035 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003036
3037 if (getenv("LIBCLANG_NOTHREADS")) {
3038 clang_reparseTranslationUnit_Impl(&RTUI);
3039 return RTUI.result;
3040 }
3041
3042 llvm::CrashRecoveryContext CRC;
3043
3044 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3045 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003046 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003047 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003048 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3049 PrintLibclangResourceUsage(TU);
3050
3051 return RTUI.result;
3052}
3053
3054
3055CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003056 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003057 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003058 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003059 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003060
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003061 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003062 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003063}
3064
3065CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003066 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003067 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003068 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003069 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003070
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003071 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003072 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3073}
3074
3075} // end: extern "C"
3076
3077//===----------------------------------------------------------------------===//
3078// CXFile Operations.
3079//===----------------------------------------------------------------------===//
3080
3081extern "C" {
3082CXString clang_getFileName(CXFile SFile) {
3083 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003084 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003085
3086 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003087 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003088}
3089
3090time_t clang_getFileTime(CXFile SFile) {
3091 if (!SFile)
3092 return 0;
3093
3094 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3095 return FEnt->getModificationTime();
3096}
3097
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003098CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003099 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003100 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003101 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003102 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003103
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003104 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003105
3106 FileManager &FMgr = CXXUnit->getFileManager();
3107 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3108}
3109
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003110unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3111 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003112 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003113 LOG_BAD_TU(TU);
3114 return 0;
3115 }
3116
3117 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003118 return 0;
3119
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003120 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003121 FileEntry *FEnt = static_cast<FileEntry *>(file);
3122 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3123 .isFileMultipleIncludeGuarded(FEnt);
3124}
3125
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003126int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3127 if (!file || !outID)
3128 return 1;
3129
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003130 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003131 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3132 outID->data[0] = ID.getDevice();
3133 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003134 outID->data[2] = FEnt->getModificationTime();
3135 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003136}
3137
Guy Benyei11169dd2012-12-18 14:30:41 +00003138} // end: extern "C"
3139
3140//===----------------------------------------------------------------------===//
3141// CXCursor Operations.
3142//===----------------------------------------------------------------------===//
3143
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003144static const Decl *getDeclFromExpr(const Stmt *E) {
3145 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003146 return getDeclFromExpr(CE->getSubExpr());
3147
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003148 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003149 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003150 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003151 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003152 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003153 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003154 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003155 if (PRE->isExplicitProperty())
3156 return PRE->getExplicitProperty();
3157 // It could be messaging both getter and setter as in:
3158 // ++myobj.myprop;
3159 // in which case prefer to associate the setter since it is less obvious
3160 // from inspecting the source that the setter is going to get called.
3161 if (PRE->isMessagingSetter())
3162 return PRE->getImplicitPropertySetter();
3163 return PRE->getImplicitPropertyGetter();
3164 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003165 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003166 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003167 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003168 if (Expr *Src = OVE->getSourceExpr())
3169 return getDeclFromExpr(Src);
3170
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003171 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003172 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003173 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003174 if (!CE->isElidable())
3175 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003176 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003177 return OME->getMethodDecl();
3178
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003179 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003180 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003181 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003182 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3183 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003184 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003185 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3186 isa<ParmVarDecl>(SizeOfPack->getPack()))
3187 return SizeOfPack->getPack();
3188
3189 return 0;
3190}
3191
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003192static SourceLocation getLocationFromExpr(const Expr *E) {
3193 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003194 return getLocationFromExpr(CE->getSubExpr());
3195
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003196 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003197 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003198 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003199 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003200 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003201 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003202 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003203 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003204 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003205 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003206 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003207 return PropRef->getLocation();
3208
3209 return E->getLocStart();
3210}
3211
3212extern "C" {
3213
3214unsigned clang_visitChildren(CXCursor parent,
3215 CXCursorVisitor visitor,
3216 CXClientData client_data) {
3217 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3218 /*VisitPreprocessorLast=*/false);
3219 return CursorVis.VisitChildren(parent);
3220}
3221
3222#ifndef __has_feature
3223#define __has_feature(x) 0
3224#endif
3225#if __has_feature(blocks)
3226typedef enum CXChildVisitResult
3227 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3228
3229static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3230 CXClientData client_data) {
3231 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3232 return block(cursor, parent);
3233}
3234#else
3235// If we are compiled with a compiler that doesn't have native blocks support,
3236// define and call the block manually, so the
3237typedef struct _CXChildVisitResult
3238{
3239 void *isa;
3240 int flags;
3241 int reserved;
3242 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3243 CXCursor);
3244} *CXCursorVisitorBlock;
3245
3246static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3247 CXClientData client_data) {
3248 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3249 return block->invoke(block, cursor, parent);
3250}
3251#endif
3252
3253
3254unsigned clang_visitChildrenWithBlock(CXCursor parent,
3255 CXCursorVisitorBlock block) {
3256 return clang_visitChildren(parent, visitWithBlock, block);
3257}
3258
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003259static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003260 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003261 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003262
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003263 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003264 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003265 if (const ObjCPropertyImplDecl *PropImpl =
3266 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003267 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003268 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003269
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003270 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003271 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003272 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003273
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003274 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003275 }
3276
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003277 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003278 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003279
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003280 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003281 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3282 // and returns different names. NamedDecl returns the class name and
3283 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003284 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003285
3286 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003287 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003288
3289 SmallString<1024> S;
3290 llvm::raw_svector_ostream os(S);
3291 ND->printName(os);
3292
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003293 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003294}
3295
3296CXString clang_getCursorSpelling(CXCursor C) {
3297 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003298 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003299
3300 if (clang_isReference(C.kind)) {
3301 switch (C.kind) {
3302 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003303 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003304 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003305 }
3306 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003307 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003308 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003309 }
3310 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003311 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003312 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003313 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003314 }
3315 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003316 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003317 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003318 }
3319 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003320 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003321 assert(Type && "Missing type decl");
3322
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003323 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003324 getAsString());
3325 }
3326 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003327 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003328 assert(Template && "Missing template decl");
3329
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003330 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003331 }
3332
3333 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003334 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003335 assert(NS && "Missing namespace decl");
3336
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003337 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 }
3339
3340 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003341 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003342 assert(Field && "Missing member decl");
3343
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003344 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003345 }
3346
3347 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003348 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 assert(Label && "Missing label");
3350
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003351 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003352 }
3353
3354 case CXCursor_OverloadedDeclRef: {
3355 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003356 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3357 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003358 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003359 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003360 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003361 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003362 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003363 OverloadedTemplateStorage *Ovl
3364 = Storage.get<OverloadedTemplateStorage*>();
3365 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003366 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003367 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003368 }
3369
3370 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003371 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003372 assert(Var && "Missing variable decl");
3373
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003374 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003375 }
3376
3377 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003378 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003379 }
3380 }
3381
3382 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003383 const Expr *E = getCursorExpr(C);
3384
3385 if (C.kind == CXCursor_ObjCStringLiteral ||
3386 C.kind == CXCursor_StringLiteral) {
3387 const StringLiteral *SLit;
3388 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3389 SLit = OSL->getString();
3390 } else {
3391 SLit = cast<StringLiteral>(E);
3392 }
3393 SmallString<256> Buf;
3394 llvm::raw_svector_ostream OS(Buf);
3395 SLit->outputString(OS);
3396 return cxstring::createDup(OS.str());
3397 }
3398
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003399 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003400 if (D)
3401 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003402 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003403 }
3404
3405 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003406 const Stmt *S = getCursorStmt(C);
3407 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003408 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003409
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003410 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003411 }
3412
3413 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003414 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003415 ->getNameStart());
3416
3417 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003418 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003419 ->getNameStart());
3420
3421 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003422 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003423
3424 if (clang_isDeclaration(C.kind))
3425 return getDeclSpelling(getCursorDecl(C));
3426
3427 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003428 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003429 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003430 }
3431
3432 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003433 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003434 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003435 }
3436
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003437 if (C.kind == CXCursor_PackedAttr) {
3438 return cxstring::createRef("packed");
3439 }
3440
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003441 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003442}
3443
3444CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3445 unsigned pieceIndex,
3446 unsigned options) {
3447 if (clang_Cursor_isNull(C))
3448 return clang_getNullRange();
3449
3450 ASTContext &Ctx = getCursorContext(C);
3451
3452 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003453 const Stmt *S = getCursorStmt(C);
3454 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003455 if (pieceIndex > 0)
3456 return clang_getNullRange();
3457 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3458 }
3459
3460 return clang_getNullRange();
3461 }
3462
3463 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003464 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003465 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3466 if (pieceIndex >= ME->getNumSelectorLocs())
3467 return clang_getNullRange();
3468 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3469 }
3470 }
3471
3472 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3473 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003474 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003475 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3476 if (pieceIndex >= MD->getNumSelectorLocs())
3477 return clang_getNullRange();
3478 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3479 }
3480 }
3481
3482 if (C.kind == CXCursor_ObjCCategoryDecl ||
3483 C.kind == CXCursor_ObjCCategoryImplDecl) {
3484 if (pieceIndex > 0)
3485 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003486 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003487 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3488 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003489 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003490 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3491 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3492 }
3493
3494 if (C.kind == CXCursor_ModuleImportDecl) {
3495 if (pieceIndex > 0)
3496 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003497 if (const ImportDecl *ImportD =
3498 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003499 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3500 if (!Locs.empty())
3501 return cxloc::translateSourceRange(Ctx,
3502 SourceRange(Locs.front(), Locs.back()));
3503 }
3504 return clang_getNullRange();
3505 }
3506
3507 // FIXME: A CXCursor_InclusionDirective should give the location of the
3508 // filename, but we don't keep track of this.
3509
3510 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3511 // but we don't keep track of this.
3512
3513 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3514 // but we don't keep track of this.
3515
3516 // Default handling, give the location of the cursor.
3517
3518 if (pieceIndex > 0)
3519 return clang_getNullRange();
3520
3521 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3522 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3523 return cxloc::translateSourceRange(Ctx, Loc);
3524}
3525
3526CXString clang_getCursorDisplayName(CXCursor C) {
3527 if (!clang_isDeclaration(C.kind))
3528 return clang_getCursorSpelling(C);
3529
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003530 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003531 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003532 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003533
3534 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003535 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003536 D = FunTmpl->getTemplatedDecl();
3537
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003538 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003539 SmallString<64> Str;
3540 llvm::raw_svector_ostream OS(Str);
3541 OS << *Function;
3542 if (Function->getPrimaryTemplate())
3543 OS << "<>";
3544 OS << "(";
3545 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3546 if (I)
3547 OS << ", ";
3548 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3549 }
3550
3551 if (Function->isVariadic()) {
3552 if (Function->getNumParams())
3553 OS << ", ";
3554 OS << "...";
3555 }
3556 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003557 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003558 }
3559
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003560 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003561 SmallString<64> Str;
3562 llvm::raw_svector_ostream OS(Str);
3563 OS << *ClassTemplate;
3564 OS << "<";
3565 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3566 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3567 if (I)
3568 OS << ", ";
3569
3570 NamedDecl *Param = Params->getParam(I);
3571 if (Param->getIdentifier()) {
3572 OS << Param->getIdentifier()->getName();
3573 continue;
3574 }
3575
3576 // There is no parameter name, which makes this tricky. Try to come up
3577 // with something useful that isn't too long.
3578 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3579 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3580 else if (NonTypeTemplateParmDecl *NTTP
3581 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3582 OS << NTTP->getType().getAsString(Policy);
3583 else
3584 OS << "template<...> class";
3585 }
3586
3587 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003588 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003589 }
3590
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003591 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003592 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3593 // If the type was explicitly written, use that.
3594 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003595 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003596
Benjamin Kramer9170e912013-02-22 15:46:01 +00003597 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003598 llvm::raw_svector_ostream OS(Str);
3599 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003600 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003601 ClassSpec->getTemplateArgs().data(),
3602 ClassSpec->getTemplateArgs().size(),
3603 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003604 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003605 }
3606
3607 return clang_getCursorSpelling(C);
3608}
3609
3610CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3611 switch (Kind) {
3612 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003613 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003614 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003615 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003616 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003617 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003618 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003619 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003620 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003621 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003622 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003623 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003624 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003625 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003626 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003627 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003628 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003629 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003630 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003631 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003632 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003633 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003635 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003637 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003641 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003643 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003645 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003647 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003651 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003653 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003655 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003659 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003663 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003665 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003673 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003740 case CXCursor_ObjCSelfExpr:
3741 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003858 case CXCursor_PackedAttr:
3859 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003908 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003909 return cxstring::createRef("OMPParallelDirective");
3910 case CXCursor_OMPSimdDirective:
3911 return cxstring::createRef("OMPSimdDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 }
3913
3914 llvm_unreachable("Unhandled CXCursorKind");
3915}
3916
3917struct GetCursorData {
3918 SourceLocation TokenBeginLoc;
3919 bool PointsAtMacroArgExpansion;
3920 bool VisitedObjCPropertyImplDecl;
3921 SourceLocation VisitedDeclaratorDeclStartLoc;
3922 CXCursor &BestCursor;
3923
3924 GetCursorData(SourceManager &SM,
3925 SourceLocation tokenBegin, CXCursor &outputCursor)
3926 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3927 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3928 VisitedObjCPropertyImplDecl = false;
3929 }
3930};
3931
3932static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3933 CXCursor parent,
3934 CXClientData client_data) {
3935 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3936 CXCursor *BestCursor = &Data->BestCursor;
3937
3938 // If we point inside a macro argument we should provide info of what the
3939 // token is so use the actual cursor, don't replace it with a macro expansion
3940 // cursor.
3941 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3942 return CXChildVisit_Recurse;
3943
3944 if (clang_isDeclaration(cursor.kind)) {
3945 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003946 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003947 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3948 if (MD->isImplicit())
3949 return CXChildVisit_Break;
3950
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003951 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3953 // Check that when we have multiple @class references in the same line,
3954 // that later ones do not override the previous ones.
3955 // If we have:
3956 // @class Foo, Bar;
3957 // source ranges for both start at '@', so 'Bar' will end up overriding
3958 // 'Foo' even though the cursor location was at 'Foo'.
3959 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3960 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003961 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3963 if (PrevID != ID &&
3964 !PrevID->isThisDeclarationADefinition() &&
3965 !ID->isThisDeclarationADefinition())
3966 return CXChildVisit_Break;
3967 }
3968
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003969 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3971 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3972 // Check that when we have multiple declarators in the same line,
3973 // that later ones do not override the previous ones.
3974 // If we have:
3975 // int Foo, Bar;
3976 // source ranges for both start at 'int', so 'Bar' will end up overriding
3977 // 'Foo' even though the cursor location was at 'Foo'.
3978 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3979 return CXChildVisit_Break;
3980 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3981
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003982 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3984 (void)PropImp;
3985 // Check that when we have multiple @synthesize in the same line,
3986 // that later ones do not override the previous ones.
3987 // If we have:
3988 // @synthesize Foo, Bar;
3989 // source ranges for both start at '@', so 'Bar' will end up overriding
3990 // 'Foo' even though the cursor location was at 'Foo'.
3991 if (Data->VisitedObjCPropertyImplDecl)
3992 return CXChildVisit_Break;
3993 Data->VisitedObjCPropertyImplDecl = true;
3994 }
3995 }
3996
3997 if (clang_isExpression(cursor.kind) &&
3998 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003999 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004000 // Avoid having the cursor of an expression replace the declaration cursor
4001 // when the expression source range overlaps the declaration range.
4002 // This can happen for C++ constructor expressions whose range generally
4003 // include the variable declaration, e.g.:
4004 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4005 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4006 D->getLocation() == Data->TokenBeginLoc)
4007 return CXChildVisit_Break;
4008 }
4009 }
4010
4011 // If our current best cursor is the construction of a temporary object,
4012 // don't replace that cursor with a type reference, because we want
4013 // clang_getCursor() to point at the constructor.
4014 if (clang_isExpression(BestCursor->kind) &&
4015 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4016 cursor.kind == CXCursor_TypeRef) {
4017 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4018 // as having the actual point on the type reference.
4019 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4020 return CXChildVisit_Recurse;
4021 }
4022
4023 *BestCursor = cursor;
4024 return CXChildVisit_Recurse;
4025}
4026
4027CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004028 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004029 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004030 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004031 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004032
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004033 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4035
4036 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4037 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4038
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004039 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 CXFile SearchFile;
4041 unsigned SearchLine, SearchColumn;
4042 CXFile ResultFile;
4043 unsigned ResultLine, ResultColumn;
4044 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4045 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4046 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4047
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004048 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4049 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 &ResultColumn, 0);
4051 SearchFileName = clang_getFileName(SearchFile);
4052 ResultFileName = clang_getFileName(ResultFile);
4053 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4054 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004055 *Log << llvm::format("(%s:%d:%d) = %s",
4056 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4057 clang_getCString(KindSpelling))
4058 << llvm::format("(%s:%d:%d):%s%s",
4059 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4060 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 clang_disposeString(SearchFileName);
4062 clang_disposeString(ResultFileName);
4063 clang_disposeString(KindSpelling);
4064 clang_disposeString(USR);
4065
4066 CXCursor Definition = clang_getCursorDefinition(Result);
4067 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4068 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4069 CXString DefinitionKindSpelling
4070 = clang_getCursorKindSpelling(Definition.kind);
4071 CXFile DefinitionFile;
4072 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004073 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 &DefinitionLine, &DefinitionColumn, 0);
4075 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004076 *Log << llvm::format(" -> %s(%s:%d:%d)",
4077 clang_getCString(DefinitionKindSpelling),
4078 clang_getCString(DefinitionFileName),
4079 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 clang_disposeString(DefinitionFileName);
4081 clang_disposeString(DefinitionKindSpelling);
4082 }
4083 }
4084
4085 return Result;
4086}
4087
4088CXCursor clang_getNullCursor(void) {
4089 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4090}
4091
4092unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004093 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4094 // can't set consistently. For example, when visiting a DeclStmt we will set
4095 // it but we don't set it on the result of clang_getCursorDefinition for
4096 // a reference of the same declaration.
4097 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4098 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4099 // to provide that kind of info.
4100 if (clang_isDeclaration(X.kind))
4101 X.data[1] = 0;
4102 if (clang_isDeclaration(Y.kind))
4103 Y.data[1] = 0;
4104
Guy Benyei11169dd2012-12-18 14:30:41 +00004105 return X == Y;
4106}
4107
4108unsigned clang_hashCursor(CXCursor C) {
4109 unsigned Index = 0;
4110 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4111 Index = 1;
4112
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004113 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 std::make_pair(C.kind, C.data[Index]));
4115}
4116
4117unsigned clang_isInvalid(enum CXCursorKind K) {
4118 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4119}
4120
4121unsigned clang_isDeclaration(enum CXCursorKind K) {
4122 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4123 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4124}
4125
4126unsigned clang_isReference(enum CXCursorKind K) {
4127 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4128}
4129
4130unsigned clang_isExpression(enum CXCursorKind K) {
4131 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4132}
4133
4134unsigned clang_isStatement(enum CXCursorKind K) {
4135 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4136}
4137
4138unsigned clang_isAttribute(enum CXCursorKind K) {
4139 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4140}
4141
4142unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4143 return K == CXCursor_TranslationUnit;
4144}
4145
4146unsigned clang_isPreprocessing(enum CXCursorKind K) {
4147 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4148}
4149
4150unsigned clang_isUnexposed(enum CXCursorKind K) {
4151 switch (K) {
4152 case CXCursor_UnexposedDecl:
4153 case CXCursor_UnexposedExpr:
4154 case CXCursor_UnexposedStmt:
4155 case CXCursor_UnexposedAttr:
4156 return true;
4157 default:
4158 return false;
4159 }
4160}
4161
4162CXCursorKind clang_getCursorKind(CXCursor C) {
4163 return C.kind;
4164}
4165
4166CXSourceLocation clang_getCursorLocation(CXCursor C) {
4167 if (clang_isReference(C.kind)) {
4168 switch (C.kind) {
4169 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004170 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004171 = getCursorObjCSuperClassRef(C);
4172 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4173 }
4174
4175 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004176 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 = getCursorObjCProtocolRef(C);
4178 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4179 }
4180
4181 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004182 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 = getCursorObjCClassRef(C);
4184 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4185 }
4186
4187 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004188 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4190 }
4191
4192 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004193 std::pair<const TemplateDecl *, SourceLocation> P =
4194 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4196 }
4197
4198 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004199 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4201 }
4202
4203 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004204 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4206 }
4207
4208 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004209 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4211 }
4212
4213 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004214 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 if (!BaseSpec)
4216 return clang_getNullLocation();
4217
4218 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4219 return cxloc::translateSourceLocation(getCursorContext(C),
4220 TSInfo->getTypeLoc().getBeginLoc());
4221
4222 return cxloc::translateSourceLocation(getCursorContext(C),
4223 BaseSpec->getLocStart());
4224 }
4225
4226 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004227 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004228 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4229 }
4230
4231 case CXCursor_OverloadedDeclRef:
4232 return cxloc::translateSourceLocation(getCursorContext(C),
4233 getCursorOverloadedDeclRef(C).second);
4234
4235 default:
4236 // FIXME: Need a way to enumerate all non-reference cases.
4237 llvm_unreachable("Missed a reference kind");
4238 }
4239 }
4240
4241 if (clang_isExpression(C.kind))
4242 return cxloc::translateSourceLocation(getCursorContext(C),
4243 getLocationFromExpr(getCursorExpr(C)));
4244
4245 if (clang_isStatement(C.kind))
4246 return cxloc::translateSourceLocation(getCursorContext(C),
4247 getCursorStmt(C)->getLocStart());
4248
4249 if (C.kind == CXCursor_PreprocessingDirective) {
4250 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4251 return cxloc::translateSourceLocation(getCursorContext(C), L);
4252 }
4253
4254 if (C.kind == CXCursor_MacroExpansion) {
4255 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004256 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004257 return cxloc::translateSourceLocation(getCursorContext(C), L);
4258 }
4259
4260 if (C.kind == CXCursor_MacroDefinition) {
4261 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4262 return cxloc::translateSourceLocation(getCursorContext(C), L);
4263 }
4264
4265 if (C.kind == CXCursor_InclusionDirective) {
4266 SourceLocation L
4267 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4268 return cxloc::translateSourceLocation(getCursorContext(C), L);
4269 }
4270
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004271 if (clang_isAttribute(C.kind)) {
4272 SourceLocation L
4273 = cxcursor::getCursorAttr(C)->getLocation();
4274 return cxloc::translateSourceLocation(getCursorContext(C), L);
4275 }
4276
Guy Benyei11169dd2012-12-18 14:30:41 +00004277 if (!clang_isDeclaration(C.kind))
4278 return clang_getNullLocation();
4279
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004280 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004281 if (!D)
4282 return clang_getNullLocation();
4283
4284 SourceLocation Loc = D->getLocation();
4285 // FIXME: Multiple variables declared in a single declaration
4286 // currently lack the information needed to correctly determine their
4287 // ranges when accounting for the type-specifier. We use context
4288 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4289 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004290 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004291 if (!cxcursor::isFirstInDeclGroup(C))
4292 Loc = VD->getLocation();
4293 }
4294
4295 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004296 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004297 Loc = MD->getSelectorStartLoc();
4298
4299 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4300}
4301
4302} // end extern "C"
4303
4304CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4305 assert(TU);
4306
4307 // Guard against an invalid SourceLocation, or we may assert in one
4308 // of the following calls.
4309 if (SLoc.isInvalid())
4310 return clang_getNullCursor();
4311
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004312 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004313
4314 // Translate the given source location to make it point at the beginning of
4315 // the token under the cursor.
4316 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4317 CXXUnit->getASTContext().getLangOpts());
4318
4319 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4320 if (SLoc.isValid()) {
4321 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4322 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4323 /*VisitPreprocessorLast=*/true,
4324 /*VisitIncludedEntities=*/false,
4325 SourceLocation(SLoc));
4326 CursorVis.visitFileRegion();
4327 }
4328
4329 return Result;
4330}
4331
4332static SourceRange getRawCursorExtent(CXCursor C) {
4333 if (clang_isReference(C.kind)) {
4334 switch (C.kind) {
4335 case CXCursor_ObjCSuperClassRef:
4336 return getCursorObjCSuperClassRef(C).second;
4337
4338 case CXCursor_ObjCProtocolRef:
4339 return getCursorObjCProtocolRef(C).second;
4340
4341 case CXCursor_ObjCClassRef:
4342 return getCursorObjCClassRef(C).second;
4343
4344 case CXCursor_TypeRef:
4345 return getCursorTypeRef(C).second;
4346
4347 case CXCursor_TemplateRef:
4348 return getCursorTemplateRef(C).second;
4349
4350 case CXCursor_NamespaceRef:
4351 return getCursorNamespaceRef(C).second;
4352
4353 case CXCursor_MemberRef:
4354 return getCursorMemberRef(C).second;
4355
4356 case CXCursor_CXXBaseSpecifier:
4357 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4358
4359 case CXCursor_LabelRef:
4360 return getCursorLabelRef(C).second;
4361
4362 case CXCursor_OverloadedDeclRef:
4363 return getCursorOverloadedDeclRef(C).second;
4364
4365 case CXCursor_VariableRef:
4366 return getCursorVariableRef(C).second;
4367
4368 default:
4369 // FIXME: Need a way to enumerate all non-reference cases.
4370 llvm_unreachable("Missed a reference kind");
4371 }
4372 }
4373
4374 if (clang_isExpression(C.kind))
4375 return getCursorExpr(C)->getSourceRange();
4376
4377 if (clang_isStatement(C.kind))
4378 return getCursorStmt(C)->getSourceRange();
4379
4380 if (clang_isAttribute(C.kind))
4381 return getCursorAttr(C)->getRange();
4382
4383 if (C.kind == CXCursor_PreprocessingDirective)
4384 return cxcursor::getCursorPreprocessingDirective(C);
4385
4386 if (C.kind == CXCursor_MacroExpansion) {
4387 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004388 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004389 return TU->mapRangeFromPreamble(Range);
4390 }
4391
4392 if (C.kind == CXCursor_MacroDefinition) {
4393 ASTUnit *TU = getCursorASTUnit(C);
4394 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4395 return TU->mapRangeFromPreamble(Range);
4396 }
4397
4398 if (C.kind == CXCursor_InclusionDirective) {
4399 ASTUnit *TU = getCursorASTUnit(C);
4400 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4401 return TU->mapRangeFromPreamble(Range);
4402 }
4403
4404 if (C.kind == CXCursor_TranslationUnit) {
4405 ASTUnit *TU = getCursorASTUnit(C);
4406 FileID MainID = TU->getSourceManager().getMainFileID();
4407 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4408 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4409 return SourceRange(Start, End);
4410 }
4411
4412 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004413 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004414 if (!D)
4415 return SourceRange();
4416
4417 SourceRange R = D->getSourceRange();
4418 // FIXME: Multiple variables declared in a single declaration
4419 // currently lack the information needed to correctly determine their
4420 // ranges when accounting for the type-specifier. We use context
4421 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4422 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004423 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004424 if (!cxcursor::isFirstInDeclGroup(C))
4425 R.setBegin(VD->getLocation());
4426 }
4427 return R;
4428 }
4429 return SourceRange();
4430}
4431
4432/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4433/// the decl-specifier-seq for declarations.
4434static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4435 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004436 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004437 if (!D)
4438 return SourceRange();
4439
4440 SourceRange R = D->getSourceRange();
4441
4442 // Adjust the start of the location for declarations preceded by
4443 // declaration specifiers.
4444 SourceLocation StartLoc;
4445 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4446 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4447 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004448 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004449 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4450 StartLoc = TI->getTypeLoc().getLocStart();
4451 }
4452
4453 if (StartLoc.isValid() && R.getBegin().isValid() &&
4454 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4455 R.setBegin(StartLoc);
4456
4457 // FIXME: Multiple variables declared in a single declaration
4458 // currently lack the information needed to correctly determine their
4459 // ranges when accounting for the type-specifier. We use context
4460 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4461 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004462 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004463 if (!cxcursor::isFirstInDeclGroup(C))
4464 R.setBegin(VD->getLocation());
4465 }
4466
4467 return R;
4468 }
4469
4470 return getRawCursorExtent(C);
4471}
4472
4473extern "C" {
4474
4475CXSourceRange clang_getCursorExtent(CXCursor C) {
4476 SourceRange R = getRawCursorExtent(C);
4477 if (R.isInvalid())
4478 return clang_getNullRange();
4479
4480 return cxloc::translateSourceRange(getCursorContext(C), R);
4481}
4482
4483CXCursor clang_getCursorReferenced(CXCursor C) {
4484 if (clang_isInvalid(C.kind))
4485 return clang_getNullCursor();
4486
4487 CXTranslationUnit tu = getCursorTU(C);
4488 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004489 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004490 if (!D)
4491 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004492 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004493 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004494 if (const ObjCPropertyImplDecl *PropImpl =
4495 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004496 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4497 return MakeCXCursor(Property, tu);
4498
4499 return C;
4500 }
4501
4502 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004503 const Expr *E = getCursorExpr(C);
4504 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004505 if (D) {
4506 CXCursor declCursor = MakeCXCursor(D, tu);
4507 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4508 declCursor);
4509 return declCursor;
4510 }
4511
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004512 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004513 return MakeCursorOverloadedDeclRef(Ovl, tu);
4514
4515 return clang_getNullCursor();
4516 }
4517
4518 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004519 const Stmt *S = getCursorStmt(C);
4520 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004521 if (LabelDecl *label = Goto->getLabel())
4522 if (LabelStmt *labelS = label->getStmt())
4523 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4524
4525 return clang_getNullCursor();
4526 }
4527
4528 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004529 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004530 return MakeMacroDefinitionCursor(Def, tu);
4531 }
4532
4533 if (!clang_isReference(C.kind))
4534 return clang_getNullCursor();
4535
4536 switch (C.kind) {
4537 case CXCursor_ObjCSuperClassRef:
4538 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4539
4540 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004541 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4542 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004543 return MakeCXCursor(Def, tu);
4544
4545 return MakeCXCursor(Prot, tu);
4546 }
4547
4548 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004549 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4550 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004551 return MakeCXCursor(Def, tu);
4552
4553 return MakeCXCursor(Class, tu);
4554 }
4555
4556 case CXCursor_TypeRef:
4557 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4558
4559 case CXCursor_TemplateRef:
4560 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4561
4562 case CXCursor_NamespaceRef:
4563 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4564
4565 case CXCursor_MemberRef:
4566 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4567
4568 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004569 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004570 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4571 tu ));
4572 }
4573
4574 case CXCursor_LabelRef:
4575 // FIXME: We end up faking the "parent" declaration here because we
4576 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004577 return MakeCXCursor(getCursorLabelRef(C).first,
4578 cxtu::getASTUnit(tu)->getASTContext()
4579 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004580 tu);
4581
4582 case CXCursor_OverloadedDeclRef:
4583 return C;
4584
4585 case CXCursor_VariableRef:
4586 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4587
4588 default:
4589 // We would prefer to enumerate all non-reference cursor kinds here.
4590 llvm_unreachable("Unhandled reference cursor kind");
4591 }
4592}
4593
4594CXCursor clang_getCursorDefinition(CXCursor C) {
4595 if (clang_isInvalid(C.kind))
4596 return clang_getNullCursor();
4597
4598 CXTranslationUnit TU = getCursorTU(C);
4599
4600 bool WasReference = false;
4601 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4602 C = clang_getCursorReferenced(C);
4603 WasReference = true;
4604 }
4605
4606 if (C.kind == CXCursor_MacroExpansion)
4607 return clang_getCursorReferenced(C);
4608
4609 if (!clang_isDeclaration(C.kind))
4610 return clang_getNullCursor();
4611
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004612 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004613 if (!D)
4614 return clang_getNullCursor();
4615
4616 switch (D->getKind()) {
4617 // Declaration kinds that don't really separate the notions of
4618 // declaration and definition.
4619 case Decl::Namespace:
4620 case Decl::Typedef:
4621 case Decl::TypeAlias:
4622 case Decl::TypeAliasTemplate:
4623 case Decl::TemplateTypeParm:
4624 case Decl::EnumConstant:
4625 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004626 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004627 case Decl::IndirectField:
4628 case Decl::ObjCIvar:
4629 case Decl::ObjCAtDefsField:
4630 case Decl::ImplicitParam:
4631 case Decl::ParmVar:
4632 case Decl::NonTypeTemplateParm:
4633 case Decl::TemplateTemplateParm:
4634 case Decl::ObjCCategoryImpl:
4635 case Decl::ObjCImplementation:
4636 case Decl::AccessSpec:
4637 case Decl::LinkageSpec:
4638 case Decl::ObjCPropertyImpl:
4639 case Decl::FileScopeAsm:
4640 case Decl::StaticAssert:
4641 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004642 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004643 case Decl::Label: // FIXME: Is this right??
4644 case Decl::ClassScopeFunctionSpecialization:
4645 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004646 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004647 return C;
4648
4649 // Declaration kinds that don't make any sense here, but are
4650 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004651 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004652 case Decl::TranslationUnit:
4653 break;
4654
4655 // Declaration kinds for which the definition is not resolvable.
4656 case Decl::UnresolvedUsingTypename:
4657 case Decl::UnresolvedUsingValue:
4658 break;
4659
4660 case Decl::UsingDirective:
4661 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4662 TU);
4663
4664 case Decl::NamespaceAlias:
4665 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4666
4667 case Decl::Enum:
4668 case Decl::Record:
4669 case Decl::CXXRecord:
4670 case Decl::ClassTemplateSpecialization:
4671 case Decl::ClassTemplatePartialSpecialization:
4672 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4673 return MakeCXCursor(Def, TU);
4674 return clang_getNullCursor();
4675
4676 case Decl::Function:
4677 case Decl::CXXMethod:
4678 case Decl::CXXConstructor:
4679 case Decl::CXXDestructor:
4680 case Decl::CXXConversion: {
4681 const FunctionDecl *Def = 0;
4682 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004683 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004684 return clang_getNullCursor();
4685 }
4686
Larisse Voufo39a1e502013-08-06 01:03:05 +00004687 case Decl::Var:
4688 case Decl::VarTemplateSpecialization:
4689 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004690 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004691 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004692 return MakeCXCursor(Def, TU);
4693 return clang_getNullCursor();
4694 }
4695
4696 case Decl::FunctionTemplate: {
4697 const FunctionDecl *Def = 0;
4698 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4699 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4700 return clang_getNullCursor();
4701 }
4702
4703 case Decl::ClassTemplate: {
4704 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4705 ->getDefinition())
4706 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4707 TU);
4708 return clang_getNullCursor();
4709 }
4710
Larisse Voufo39a1e502013-08-06 01:03:05 +00004711 case Decl::VarTemplate: {
4712 if (VarDecl *Def =
4713 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4714 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4715 return clang_getNullCursor();
4716 }
4717
Guy Benyei11169dd2012-12-18 14:30:41 +00004718 case Decl::Using:
4719 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4720 D->getLocation(), TU);
4721
4722 case Decl::UsingShadow:
4723 return clang_getCursorDefinition(
4724 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4725 TU));
4726
4727 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004728 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004729 if (Method->isThisDeclarationADefinition())
4730 return C;
4731
4732 // Dig out the method definition in the associated
4733 // @implementation, if we have it.
4734 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004735 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004736 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4737 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4738 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4739 Method->isInstanceMethod()))
4740 if (Def->isThisDeclarationADefinition())
4741 return MakeCXCursor(Def, TU);
4742
4743 return clang_getNullCursor();
4744 }
4745
4746 case Decl::ObjCCategory:
4747 if (ObjCCategoryImplDecl *Impl
4748 = cast<ObjCCategoryDecl>(D)->getImplementation())
4749 return MakeCXCursor(Impl, TU);
4750 return clang_getNullCursor();
4751
4752 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004753 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004754 return MakeCXCursor(Def, TU);
4755 return clang_getNullCursor();
4756
4757 case Decl::ObjCInterface: {
4758 // There are two notions of a "definition" for an Objective-C
4759 // class: the interface and its implementation. When we resolved a
4760 // reference to an Objective-C class, produce the @interface as
4761 // the definition; when we were provided with the interface,
4762 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004763 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004764 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004765 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004766 return MakeCXCursor(Def, TU);
4767 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4768 return MakeCXCursor(Impl, TU);
4769 return clang_getNullCursor();
4770 }
4771
4772 case Decl::ObjCProperty:
4773 // FIXME: We don't really know where to find the
4774 // ObjCPropertyImplDecls that implement this property.
4775 return clang_getNullCursor();
4776
4777 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004778 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004779 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004780 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004781 return MakeCXCursor(Def, TU);
4782
4783 return clang_getNullCursor();
4784
4785 case Decl::Friend:
4786 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4787 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4788 return clang_getNullCursor();
4789
4790 case Decl::FriendTemplate:
4791 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4792 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4793 return clang_getNullCursor();
4794 }
4795
4796 return clang_getNullCursor();
4797}
4798
4799unsigned clang_isCursorDefinition(CXCursor C) {
4800 if (!clang_isDeclaration(C.kind))
4801 return 0;
4802
4803 return clang_getCursorDefinition(C) == C;
4804}
4805
4806CXCursor clang_getCanonicalCursor(CXCursor C) {
4807 if (!clang_isDeclaration(C.kind))
4808 return C;
4809
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004810 if (const Decl *D = getCursorDecl(C)) {
4811 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004812 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4813 return MakeCXCursor(CatD, getCursorTU(C));
4814
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004815 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4816 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004817 return MakeCXCursor(IFD, getCursorTU(C));
4818
4819 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4820 }
4821
4822 return C;
4823}
4824
4825int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4826 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4827}
4828
4829unsigned clang_getNumOverloadedDecls(CXCursor C) {
4830 if (C.kind != CXCursor_OverloadedDeclRef)
4831 return 0;
4832
4833 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004834 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004835 return E->getNumDecls();
4836
4837 if (OverloadedTemplateStorage *S
4838 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4839 return S->size();
4840
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004841 const Decl *D = Storage.get<const Decl *>();
4842 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004843 return Using->shadow_size();
4844
4845 return 0;
4846}
4847
4848CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4849 if (cursor.kind != CXCursor_OverloadedDeclRef)
4850 return clang_getNullCursor();
4851
4852 if (index >= clang_getNumOverloadedDecls(cursor))
4853 return clang_getNullCursor();
4854
4855 CXTranslationUnit TU = getCursorTU(cursor);
4856 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004857 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004858 return MakeCXCursor(E->decls_begin()[index], TU);
4859
4860 if (OverloadedTemplateStorage *S
4861 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4862 return MakeCXCursor(S->begin()[index], TU);
4863
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004864 const Decl *D = Storage.get<const Decl *>();
4865 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004866 // FIXME: This is, unfortunately, linear time.
4867 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4868 std::advance(Pos, index);
4869 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4870 }
4871
4872 return clang_getNullCursor();
4873}
4874
4875void clang_getDefinitionSpellingAndExtent(CXCursor C,
4876 const char **startBuf,
4877 const char **endBuf,
4878 unsigned *startLine,
4879 unsigned *startColumn,
4880 unsigned *endLine,
4881 unsigned *endColumn) {
4882 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004883 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004884 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4885
4886 SourceManager &SM = FD->getASTContext().getSourceManager();
4887 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4888 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4889 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4890 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4891 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4892 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4893}
4894
4895
4896CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4897 unsigned PieceIndex) {
4898 RefNamePieces Pieces;
4899
4900 switch (C.kind) {
4901 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004902 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004903 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4904 E->getQualifierLoc().getSourceRange());
4905 break;
4906
4907 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004908 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004909 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4910 E->getQualifierLoc().getSourceRange(),
4911 E->getOptionalExplicitTemplateArgs());
4912 break;
4913
4914 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004915 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004916 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004917 const Expr *Callee = OCE->getCallee();
4918 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004919 Callee = ICE->getSubExpr();
4920
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004921 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004922 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4923 DRE->getQualifierLoc().getSourceRange());
4924 }
4925 break;
4926
4927 default:
4928 break;
4929 }
4930
4931 if (Pieces.empty()) {
4932 if (PieceIndex == 0)
4933 return clang_getCursorExtent(C);
4934 } else if (PieceIndex < Pieces.size()) {
4935 SourceRange R = Pieces[PieceIndex];
4936 if (R.isValid())
4937 return cxloc::translateSourceRange(getCursorContext(C), R);
4938 }
4939
4940 return clang_getNullRange();
4941}
4942
4943void clang_enableStackTraces(void) {
4944 llvm::sys::PrintStackTraceOnErrorSignal();
4945}
4946
4947void clang_executeOnThread(void (*fn)(void*), void *user_data,
4948 unsigned stack_size) {
4949 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4950}
4951
4952} // end: extern "C"
4953
4954//===----------------------------------------------------------------------===//
4955// Token-based Operations.
4956//===----------------------------------------------------------------------===//
4957
4958/* CXToken layout:
4959 * int_data[0]: a CXTokenKind
4960 * int_data[1]: starting token location
4961 * int_data[2]: token length
4962 * int_data[3]: reserved
4963 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4964 * otherwise unused.
4965 */
4966extern "C" {
4967
4968CXTokenKind clang_getTokenKind(CXToken CXTok) {
4969 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4970}
4971
4972CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4973 switch (clang_getTokenKind(CXTok)) {
4974 case CXToken_Identifier:
4975 case CXToken_Keyword:
4976 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004977 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004978 ->getNameStart());
4979
4980 case CXToken_Literal: {
4981 // We have stashed the starting pointer in the ptr_data field. Use it.
4982 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004983 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004984 }
4985
4986 case CXToken_Punctuation:
4987 case CXToken_Comment:
4988 break;
4989 }
4990
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004991 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004992 LOG_BAD_TU(TU);
4993 return cxstring::createEmpty();
4994 }
4995
Guy Benyei11169dd2012-12-18 14:30:41 +00004996 // We have to find the starting buffer pointer the hard way, by
4997 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004998 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004999 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005000 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005001
5002 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5003 std::pair<FileID, unsigned> LocInfo
5004 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5005 bool Invalid = false;
5006 StringRef Buffer
5007 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5008 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005009 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005010
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005011 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005012}
5013
5014CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005015 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005016 LOG_BAD_TU(TU);
5017 return clang_getNullLocation();
5018 }
5019
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005020 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005021 if (!CXXUnit)
5022 return clang_getNullLocation();
5023
5024 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5025 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5026}
5027
5028CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005029 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005030 LOG_BAD_TU(TU);
5031 return clang_getNullRange();
5032 }
5033
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005034 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005035 if (!CXXUnit)
5036 return clang_getNullRange();
5037
5038 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5039 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5040}
5041
5042static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5043 SmallVectorImpl<CXToken> &CXTokens) {
5044 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5045 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005046 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005047 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005048 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005049
5050 // Cannot tokenize across files.
5051 if (BeginLocInfo.first != EndLocInfo.first)
5052 return;
5053
5054 // Create a lexer
5055 bool Invalid = false;
5056 StringRef Buffer
5057 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5058 if (Invalid)
5059 return;
5060
5061 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5062 CXXUnit->getASTContext().getLangOpts(),
5063 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5064 Lex.SetCommentRetentionState(true);
5065
5066 // Lex tokens until we hit the end of the range.
5067 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5068 Token Tok;
5069 bool previousWasAt = false;
5070 do {
5071 // Lex the next token
5072 Lex.LexFromRawLexer(Tok);
5073 if (Tok.is(tok::eof))
5074 break;
5075
5076 // Initialize the CXToken.
5077 CXToken CXTok;
5078
5079 // - Common fields
5080 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5081 CXTok.int_data[2] = Tok.getLength();
5082 CXTok.int_data[3] = 0;
5083
5084 // - Kind-specific fields
5085 if (Tok.isLiteral()) {
5086 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005087 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005088 } else if (Tok.is(tok::raw_identifier)) {
5089 // Lookup the identifier to determine whether we have a keyword.
5090 IdentifierInfo *II
5091 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5092
5093 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5094 CXTok.int_data[0] = CXToken_Keyword;
5095 }
5096 else {
5097 CXTok.int_data[0] = Tok.is(tok::identifier)
5098 ? CXToken_Identifier
5099 : CXToken_Keyword;
5100 }
5101 CXTok.ptr_data = II;
5102 } else if (Tok.is(tok::comment)) {
5103 CXTok.int_data[0] = CXToken_Comment;
5104 CXTok.ptr_data = 0;
5105 } else {
5106 CXTok.int_data[0] = CXToken_Punctuation;
5107 CXTok.ptr_data = 0;
5108 }
5109 CXTokens.push_back(CXTok);
5110 previousWasAt = Tok.is(tok::at);
5111 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5112}
5113
5114void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5115 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005116 LOG_FUNC_SECTION {
5117 *Log << TU << ' ' << Range;
5118 }
5119
Guy Benyei11169dd2012-12-18 14:30:41 +00005120 if (Tokens)
5121 *Tokens = 0;
5122 if (NumTokens)
5123 *NumTokens = 0;
5124
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005125 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005126 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005127 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005128 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005129
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005130 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005131 if (!CXXUnit || !Tokens || !NumTokens)
5132 return;
5133
5134 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5135
5136 SourceRange R = cxloc::translateCXSourceRange(Range);
5137 if (R.isInvalid())
5138 return;
5139
5140 SmallVector<CXToken, 32> CXTokens;
5141 getTokens(CXXUnit, R, CXTokens);
5142
5143 if (CXTokens.empty())
5144 return;
5145
5146 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5147 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5148 *NumTokens = CXTokens.size();
5149}
5150
5151void clang_disposeTokens(CXTranslationUnit TU,
5152 CXToken *Tokens, unsigned NumTokens) {
5153 free(Tokens);
5154}
5155
5156} // end: extern "C"
5157
5158//===----------------------------------------------------------------------===//
5159// Token annotation APIs.
5160//===----------------------------------------------------------------------===//
5161
Guy Benyei11169dd2012-12-18 14:30:41 +00005162static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5163 CXCursor parent,
5164 CXClientData client_data);
5165static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5166 CXClientData client_data);
5167
5168namespace {
5169class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005170 CXToken *Tokens;
5171 CXCursor *Cursors;
5172 unsigned NumTokens;
5173 unsigned TokIdx;
5174 unsigned PreprocessingTokIdx;
5175 CursorVisitor AnnotateVis;
5176 SourceManager &SrcMgr;
5177 bool HasContextSensitiveKeywords;
5178
5179 struct PostChildrenInfo {
5180 CXCursor Cursor;
5181 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005182 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005183 unsigned BeforeChildrenTokenIdx;
5184 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005185 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005186
5187 CXToken &getTok(unsigned Idx) {
5188 assert(Idx < NumTokens);
5189 return Tokens[Idx];
5190 }
5191 const CXToken &getTok(unsigned Idx) const {
5192 assert(Idx < NumTokens);
5193 return Tokens[Idx];
5194 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005195 bool MoreTokens() const { return TokIdx < NumTokens; }
5196 unsigned NextToken() const { return TokIdx; }
5197 void AdvanceToken() { ++TokIdx; }
5198 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005199 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005200 }
5201 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005202 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005203 }
5204 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005205 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005206 }
5207
5208 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005209 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 SourceRange);
5211
5212public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005213 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005214 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005215 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005217 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 AnnotateTokensVisitor, this,
5219 /*VisitPreprocessorLast=*/true,
5220 /*VisitIncludedEntities=*/false,
5221 RegionOfInterest,
5222 /*VisitDeclsOnly=*/false,
5223 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005224 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005225 HasContextSensitiveKeywords(false) { }
5226
5227 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5228 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5229 bool postVisitChildren(CXCursor cursor);
5230 void AnnotateTokens();
5231
5232 /// \brief Determine whether the annotator saw any cursors that have
5233 /// context-sensitive keywords.
5234 bool hasContextSensitiveKeywords() const {
5235 return HasContextSensitiveKeywords;
5236 }
5237
5238 ~AnnotateTokensWorker() {
5239 assert(PostChildrenInfos.empty());
5240 }
5241};
5242}
5243
5244void AnnotateTokensWorker::AnnotateTokens() {
5245 // Walk the AST within the region of interest, annotating tokens
5246 // along the way.
5247 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005248}
Guy Benyei11169dd2012-12-18 14:30:41 +00005249
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005250static inline void updateCursorAnnotation(CXCursor &Cursor,
5251 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005252 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005253 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005254 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005255}
5256
5257/// \brief It annotates and advances tokens with a cursor until the comparison
5258//// between the cursor location and the source range is the same as
5259/// \arg compResult.
5260///
5261/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5262/// Pass RangeOverlap to annotate tokens inside a range.
5263void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5264 RangeComparisonResult compResult,
5265 SourceRange range) {
5266 while (MoreTokens()) {
5267 const unsigned I = NextToken();
5268 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005269 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5270 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005271
5272 SourceLocation TokLoc = GetTokenLoc(I);
5273 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005274 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005275 AdvanceToken();
5276 continue;
5277 }
5278 break;
5279 }
5280}
5281
5282/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005283/// \returns true if it advanced beyond all macro tokens, false otherwise.
5284bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005285 CXCursor updateC,
5286 RangeComparisonResult compResult,
5287 SourceRange range) {
5288 assert(MoreTokens());
5289 assert(isFunctionMacroToken(NextToken()) &&
5290 "Should be called only for macro arg tokens");
5291
5292 // This works differently than annotateAndAdvanceTokens; because expanded
5293 // macro arguments can have arbitrary translation-unit source order, we do not
5294 // advance the token index one by one until a token fails the range test.
5295 // We only advance once past all of the macro arg tokens if all of them
5296 // pass the range test. If one of them fails we keep the token index pointing
5297 // at the start of the macro arg tokens so that the failing token will be
5298 // annotated by a subsequent annotation try.
5299
5300 bool atLeastOneCompFail = false;
5301
5302 unsigned I = NextToken();
5303 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5304 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5305 if (TokLoc.isFileID())
5306 continue; // not macro arg token, it's parens or comma.
5307 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5308 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5309 Cursors[I] = updateC;
5310 } else
5311 atLeastOneCompFail = true;
5312 }
5313
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005314 if (atLeastOneCompFail)
5315 return false;
5316
5317 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5318 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005319}
5320
5321enum CXChildVisitResult
5322AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005323 SourceRange cursorRange = getRawCursorExtent(cursor);
5324 if (cursorRange.isInvalid())
5325 return CXChildVisit_Recurse;
5326
5327 if (!HasContextSensitiveKeywords) {
5328 // Objective-C properties can have context-sensitive keywords.
5329 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005330 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005331 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5332 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5333 }
5334 // Objective-C methods can have context-sensitive keywords.
5335 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5336 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005337 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005338 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5339 if (Method->getObjCDeclQualifier())
5340 HasContextSensitiveKeywords = true;
5341 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005342 for (const auto *P : Method->params()) {
5343 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005344 HasContextSensitiveKeywords = true;
5345 break;
5346 }
5347 }
5348 }
5349 }
5350 }
5351 // C++ methods can have context-sensitive keywords.
5352 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005353 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005354 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5355 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5356 HasContextSensitiveKeywords = true;
5357 }
5358 }
5359 // C++ classes can have context-sensitive keywords.
5360 else if (cursor.kind == CXCursor_StructDecl ||
5361 cursor.kind == CXCursor_ClassDecl ||
5362 cursor.kind == CXCursor_ClassTemplate ||
5363 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005364 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005365 if (D->hasAttr<FinalAttr>())
5366 HasContextSensitiveKeywords = true;
5367 }
5368 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005369
5370 // Don't override a property annotation with its getter/setter method.
5371 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5372 parent.kind == CXCursor_ObjCPropertyDecl)
5373 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005374
5375 if (clang_isPreprocessing(cursor.kind)) {
5376 // Items in the preprocessing record are kept separate from items in
5377 // declarations, so we keep a separate token index.
5378 unsigned SavedTokIdx = TokIdx;
5379 TokIdx = PreprocessingTokIdx;
5380
5381 // Skip tokens up until we catch up to the beginning of the preprocessing
5382 // entry.
5383 while (MoreTokens()) {
5384 const unsigned I = NextToken();
5385 SourceLocation TokLoc = GetTokenLoc(I);
5386 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5387 case RangeBefore:
5388 AdvanceToken();
5389 continue;
5390 case RangeAfter:
5391 case RangeOverlap:
5392 break;
5393 }
5394 break;
5395 }
5396
5397 // Look at all of the tokens within this range.
5398 while (MoreTokens()) {
5399 const unsigned I = NextToken();
5400 SourceLocation TokLoc = GetTokenLoc(I);
5401 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5402 case RangeBefore:
5403 llvm_unreachable("Infeasible");
5404 case RangeAfter:
5405 break;
5406 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005407 // For macro expansions, just note where the beginning of the macro
5408 // expansion occurs.
5409 if (cursor.kind == CXCursor_MacroExpansion) {
5410 if (TokLoc == cursorRange.getBegin())
5411 Cursors[I] = cursor;
5412 AdvanceToken();
5413 break;
5414 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005415 // We may have already annotated macro names inside macro definitions.
5416 if (Cursors[I].kind != CXCursor_MacroExpansion)
5417 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005418 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005419 continue;
5420 }
5421 break;
5422 }
5423
5424 // Save the preprocessing token index; restore the non-preprocessing
5425 // token index.
5426 PreprocessingTokIdx = TokIdx;
5427 TokIdx = SavedTokIdx;
5428 return CXChildVisit_Recurse;
5429 }
5430
5431 if (cursorRange.isInvalid())
5432 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005433
5434 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005435 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005436 const enum CXCursorKind K = clang_getCursorKind(parent);
5437 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005438 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5439 // Attributes are annotated out-of-order, skip tokens until we reach it.
5440 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005441 ? clang_getNullCursor() : parent;
5442
5443 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5444
5445 // Avoid having the cursor of an expression "overwrite" the annotation of the
5446 // variable declaration that it belongs to.
5447 // This can happen for C++ constructor expressions whose range generally
5448 // include the variable declaration, e.g.:
5449 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005450 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005451 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005452 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005453 const unsigned I = NextToken();
5454 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5455 E->getLocStart() == D->getLocation() &&
5456 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005457 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005458 AdvanceToken();
5459 }
5460 }
5461 }
5462
5463 // Before recursing into the children keep some state that we are going
5464 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5465 // extra work after the child nodes are visited.
5466 // Note that we don't call VisitChildren here to avoid traversing statements
5467 // code-recursively which can blow the stack.
5468
5469 PostChildrenInfo Info;
5470 Info.Cursor = cursor;
5471 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005472 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005473 Info.BeforeChildrenTokenIdx = NextToken();
5474 PostChildrenInfos.push_back(Info);
5475
5476 return CXChildVisit_Recurse;
5477}
5478
5479bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5480 if (PostChildrenInfos.empty())
5481 return false;
5482 const PostChildrenInfo &Info = PostChildrenInfos.back();
5483 if (!clang_equalCursors(Info.Cursor, cursor))
5484 return false;
5485
5486 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5487 const unsigned AfterChildren = NextToken();
5488 SourceRange cursorRange = Info.CursorRange;
5489
5490 // Scan the tokens that are at the end of the cursor, but are not captured
5491 // but the child cursors.
5492 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5493
5494 // Scan the tokens that are at the beginning of the cursor, but are not
5495 // capture by the child cursors.
5496 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5497 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5498 break;
5499
5500 Cursors[I] = cursor;
5501 }
5502
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005503 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5504 // encountered the attribute cursor.
5505 if (clang_isAttribute(cursor.kind))
5506 TokIdx = Info.BeforeReachingCursorIdx;
5507
Guy Benyei11169dd2012-12-18 14:30:41 +00005508 PostChildrenInfos.pop_back();
5509 return false;
5510}
5511
5512static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5513 CXCursor parent,
5514 CXClientData client_data) {
5515 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5516}
5517
5518static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5519 CXClientData client_data) {
5520 return static_cast<AnnotateTokensWorker*>(client_data)->
5521 postVisitChildren(cursor);
5522}
5523
5524namespace {
5525
5526/// \brief Uses the macro expansions in the preprocessing record to find
5527/// and mark tokens that are macro arguments. This info is used by the
5528/// AnnotateTokensWorker.
5529class MarkMacroArgTokensVisitor {
5530 SourceManager &SM;
5531 CXToken *Tokens;
5532 unsigned NumTokens;
5533 unsigned CurIdx;
5534
5535public:
5536 MarkMacroArgTokensVisitor(SourceManager &SM,
5537 CXToken *tokens, unsigned numTokens)
5538 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5539
5540 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5541 if (cursor.kind != CXCursor_MacroExpansion)
5542 return CXChildVisit_Continue;
5543
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005544 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005545 if (macroRange.getBegin() == macroRange.getEnd())
5546 return CXChildVisit_Continue; // it's not a function macro.
5547
5548 for (; CurIdx < NumTokens; ++CurIdx) {
5549 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5550 macroRange.getBegin()))
5551 break;
5552 }
5553
5554 if (CurIdx == NumTokens)
5555 return CXChildVisit_Break;
5556
5557 for (; CurIdx < NumTokens; ++CurIdx) {
5558 SourceLocation tokLoc = getTokenLoc(CurIdx);
5559 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5560 break;
5561
5562 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5563 }
5564
5565 if (CurIdx == NumTokens)
5566 return CXChildVisit_Break;
5567
5568 return CXChildVisit_Continue;
5569 }
5570
5571private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005572 CXToken &getTok(unsigned Idx) {
5573 assert(Idx < NumTokens);
5574 return Tokens[Idx];
5575 }
5576 const CXToken &getTok(unsigned Idx) const {
5577 assert(Idx < NumTokens);
5578 return Tokens[Idx];
5579 }
5580
Guy Benyei11169dd2012-12-18 14:30:41 +00005581 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005582 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005583 }
5584
5585 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5586 // The third field is reserved and currently not used. Use it here
5587 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005588 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005589 }
5590};
5591
5592} // end anonymous namespace
5593
5594static CXChildVisitResult
5595MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5596 CXClientData client_data) {
5597 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5598 parent);
5599}
5600
5601namespace {
5602 struct clang_annotateTokens_Data {
5603 CXTranslationUnit TU;
5604 ASTUnit *CXXUnit;
5605 CXToken *Tokens;
5606 unsigned NumTokens;
5607 CXCursor *Cursors;
5608 };
5609}
5610
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005611/// \brief Used by \c annotatePreprocessorTokens.
5612/// \returns true if lexing was finished, false otherwise.
5613static bool lexNext(Lexer &Lex, Token &Tok,
5614 unsigned &NextIdx, unsigned NumTokens) {
5615 if (NextIdx >= NumTokens)
5616 return true;
5617
5618 ++NextIdx;
5619 Lex.LexFromRawLexer(Tok);
5620 if (Tok.is(tok::eof))
5621 return true;
5622
5623 return false;
5624}
5625
Guy Benyei11169dd2012-12-18 14:30:41 +00005626static void annotatePreprocessorTokens(CXTranslationUnit TU,
5627 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005628 CXCursor *Cursors,
5629 CXToken *Tokens,
5630 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005631 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005632
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005633 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005634 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5635 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005636 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005637 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005638 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005639
5640 if (BeginLocInfo.first != EndLocInfo.first)
5641 return;
5642
5643 StringRef Buffer;
5644 bool Invalid = false;
5645 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5646 if (Buffer.empty() || Invalid)
5647 return;
5648
5649 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5650 CXXUnit->getASTContext().getLangOpts(),
5651 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5652 Buffer.end());
5653 Lex.SetCommentRetentionState(true);
5654
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005655 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005656 // Lex tokens in raw mode until we hit the end of the range, to avoid
5657 // entering #includes or expanding macros.
5658 while (true) {
5659 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005660 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5661 break;
5662 unsigned TokIdx = NextIdx-1;
5663 assert(Tok.getLocation() ==
5664 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005665
5666 reprocess:
5667 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005668 // We have found a preprocessing directive. Annotate the tokens
5669 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005670 //
5671 // FIXME: Some simple tests here could identify macro definitions and
5672 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005673
5674 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005675 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5676 break;
5677
5678 MacroInfo *MI = 0;
5679 if (Tok.is(tok::raw_identifier) &&
5680 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5681 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5682 break;
5683
5684 if (Tok.is(tok::raw_identifier)) {
5685 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5686 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5687 SourceLocation MappedTokLoc =
5688 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5689 MI = getMacroInfo(II, MappedTokLoc, TU);
5690 }
5691 }
5692
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005693 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005694 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005695 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5696 finished = true;
5697 break;
5698 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005699 // If we are in a macro definition, check if the token was ever a
5700 // macro name and annotate it if that's the case.
5701 if (MI) {
5702 SourceLocation SaveLoc = Tok.getLocation();
5703 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5704 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5705 Tok.setLocation(SaveLoc);
5706 if (MacroDef)
5707 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5708 Tok.getLocation(), TU);
5709 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005710 } while (!Tok.isAtStartOfLine());
5711
5712 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5713 assert(TokIdx <= LastIdx);
5714 SourceLocation EndLoc =
5715 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5716 CXCursor Cursor =
5717 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5718
5719 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005720 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005721
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005722 if (finished)
5723 break;
5724 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005725 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005726 }
5727}
5728
5729// This gets run a separate thread to avoid stack blowout.
5730static void clang_annotateTokensImpl(void *UserData) {
5731 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5732 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5733 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5734 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5735 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5736
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005737 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005738 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5739 setThreadBackgroundPriority();
5740
5741 // Determine the region of interest, which contains all of the tokens.
5742 SourceRange RegionOfInterest;
5743 RegionOfInterest.setBegin(
5744 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5745 RegionOfInterest.setEnd(
5746 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5747 Tokens[NumTokens-1])));
5748
Guy Benyei11169dd2012-12-18 14:30:41 +00005749 // Relex the tokens within the source range to look for preprocessing
5750 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005751 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005752
5753 // If begin location points inside a macro argument, set it to the expansion
5754 // location so we can have the full context when annotating semantically.
5755 {
5756 SourceManager &SM = CXXUnit->getSourceManager();
5757 SourceLocation Loc =
5758 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5759 if (Loc.isMacroID())
5760 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5761 }
5762
Guy Benyei11169dd2012-12-18 14:30:41 +00005763 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5764 // Search and mark tokens that are macro argument expansions.
5765 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5766 Tokens, NumTokens);
5767 CursorVisitor MacroArgMarker(TU,
5768 MarkMacroArgTokensVisitorDelegate, &Visitor,
5769 /*VisitPreprocessorLast=*/true,
5770 /*VisitIncludedEntities=*/false,
5771 RegionOfInterest);
5772 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5773 }
5774
5775 // Annotate all of the source locations in the region of interest that map to
5776 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005777 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005778
5779 // FIXME: We use a ridiculous stack size here because the data-recursion
5780 // algorithm uses a large stack frame than the non-data recursive version,
5781 // and AnnotationTokensWorker currently transforms the data-recursion
5782 // algorithm back into a traditional recursion by explicitly calling
5783 // VisitChildren(). We will need to remove this explicit recursive call.
5784 W.AnnotateTokens();
5785
5786 // If we ran into any entities that involve context-sensitive keywords,
5787 // take another pass through the tokens to mark them as such.
5788 if (W.hasContextSensitiveKeywords()) {
5789 for (unsigned I = 0; I != NumTokens; ++I) {
5790 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5791 continue;
5792
5793 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5794 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005795 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005796 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5797 if (Property->getPropertyAttributesAsWritten() != 0 &&
5798 llvm::StringSwitch<bool>(II->getName())
5799 .Case("readonly", true)
5800 .Case("assign", true)
5801 .Case("unsafe_unretained", true)
5802 .Case("readwrite", true)
5803 .Case("retain", true)
5804 .Case("copy", true)
5805 .Case("nonatomic", true)
5806 .Case("atomic", true)
5807 .Case("getter", true)
5808 .Case("setter", true)
5809 .Case("strong", true)
5810 .Case("weak", true)
5811 .Default(false))
5812 Tokens[I].int_data[0] = CXToken_Keyword;
5813 }
5814 continue;
5815 }
5816
5817 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5818 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5819 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5820 if (llvm::StringSwitch<bool>(II->getName())
5821 .Case("in", true)
5822 .Case("out", true)
5823 .Case("inout", true)
5824 .Case("oneway", true)
5825 .Case("bycopy", true)
5826 .Case("byref", true)
5827 .Default(false))
5828 Tokens[I].int_data[0] = CXToken_Keyword;
5829 continue;
5830 }
5831
5832 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5833 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5834 Tokens[I].int_data[0] = CXToken_Keyword;
5835 continue;
5836 }
5837 }
5838 }
5839}
5840
5841extern "C" {
5842
5843void clang_annotateTokens(CXTranslationUnit TU,
5844 CXToken *Tokens, unsigned NumTokens,
5845 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005846 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005847 LOG_BAD_TU(TU);
5848 return;
5849 }
5850 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005851 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005852 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005853 }
5854
5855 LOG_FUNC_SECTION {
5856 *Log << TU << ' ';
5857 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5858 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5859 *Log << clang_getRange(bloc, eloc);
5860 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005861
5862 // Any token we don't specifically annotate will have a NULL cursor.
5863 CXCursor C = clang_getNullCursor();
5864 for (unsigned I = 0; I != NumTokens; ++I)
5865 Cursors[I] = C;
5866
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005867 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005868 if (!CXXUnit)
5869 return;
5870
5871 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5872
5873 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5874 llvm::CrashRecoveryContext CRC;
5875 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5876 GetSafetyThreadStackSize() * 2)) {
5877 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5878 }
5879}
5880
5881} // end: extern "C"
5882
5883//===----------------------------------------------------------------------===//
5884// Operations for querying linkage of a cursor.
5885//===----------------------------------------------------------------------===//
5886
5887extern "C" {
5888CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5889 if (!clang_isDeclaration(cursor.kind))
5890 return CXLinkage_Invalid;
5891
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005892 const Decl *D = cxcursor::getCursorDecl(cursor);
5893 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005894 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005895 case NoLinkage:
5896 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005897 case InternalLinkage: return CXLinkage_Internal;
5898 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5899 case ExternalLinkage: return CXLinkage_External;
5900 };
5901
5902 return CXLinkage_Invalid;
5903}
5904} // end: extern "C"
5905
5906//===----------------------------------------------------------------------===//
5907// Operations for querying language of a cursor.
5908//===----------------------------------------------------------------------===//
5909
5910static CXLanguageKind getDeclLanguage(const Decl *D) {
5911 if (!D)
5912 return CXLanguage_C;
5913
5914 switch (D->getKind()) {
5915 default:
5916 break;
5917 case Decl::ImplicitParam:
5918 case Decl::ObjCAtDefsField:
5919 case Decl::ObjCCategory:
5920 case Decl::ObjCCategoryImpl:
5921 case Decl::ObjCCompatibleAlias:
5922 case Decl::ObjCImplementation:
5923 case Decl::ObjCInterface:
5924 case Decl::ObjCIvar:
5925 case Decl::ObjCMethod:
5926 case Decl::ObjCProperty:
5927 case Decl::ObjCPropertyImpl:
5928 case Decl::ObjCProtocol:
5929 return CXLanguage_ObjC;
5930 case Decl::CXXConstructor:
5931 case Decl::CXXConversion:
5932 case Decl::CXXDestructor:
5933 case Decl::CXXMethod:
5934 case Decl::CXXRecord:
5935 case Decl::ClassTemplate:
5936 case Decl::ClassTemplatePartialSpecialization:
5937 case Decl::ClassTemplateSpecialization:
5938 case Decl::Friend:
5939 case Decl::FriendTemplate:
5940 case Decl::FunctionTemplate:
5941 case Decl::LinkageSpec:
5942 case Decl::Namespace:
5943 case Decl::NamespaceAlias:
5944 case Decl::NonTypeTemplateParm:
5945 case Decl::StaticAssert:
5946 case Decl::TemplateTemplateParm:
5947 case Decl::TemplateTypeParm:
5948 case Decl::UnresolvedUsingTypename:
5949 case Decl::UnresolvedUsingValue:
5950 case Decl::Using:
5951 case Decl::UsingDirective:
5952 case Decl::UsingShadow:
5953 return CXLanguage_CPlusPlus;
5954 }
5955
5956 return CXLanguage_C;
5957}
5958
5959extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005960
5961static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5962 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5963 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005964
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005965 switch (D->getAvailability()) {
5966 case AR_Available:
5967 case AR_NotYetIntroduced:
5968 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005969 return getCursorAvailabilityForDecl(
5970 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005971 return CXAvailability_Available;
5972
5973 case AR_Deprecated:
5974 return CXAvailability_Deprecated;
5975
5976 case AR_Unavailable:
5977 return CXAvailability_NotAvailable;
5978 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005979
5980 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005981}
5982
Guy Benyei11169dd2012-12-18 14:30:41 +00005983enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5984 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005985 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5986 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005987
5988 return CXAvailability_Available;
5989}
5990
5991static CXVersion convertVersion(VersionTuple In) {
5992 CXVersion Out = { -1, -1, -1 };
5993 if (In.empty())
5994 return Out;
5995
5996 Out.Major = In.getMajor();
5997
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00005998 Optional<unsigned> Minor = In.getMinor();
5999 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006000 Out.Minor = *Minor;
6001 else
6002 return Out;
6003
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006004 Optional<unsigned> Subminor = In.getSubminor();
6005 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006006 Out.Subminor = *Subminor;
6007
6008 return Out;
6009}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006010
6011static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6012 int *always_deprecated,
6013 CXString *deprecated_message,
6014 int *always_unavailable,
6015 CXString *unavailable_message,
6016 CXPlatformAvailability *availability,
6017 int availability_size) {
6018 bool HadAvailAttr = false;
6019 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006020 for (auto A : D->attrs()) {
6021 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006022 HadAvailAttr = true;
6023 if (always_deprecated)
6024 *always_deprecated = 1;
6025 if (deprecated_message)
6026 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
6027 continue;
6028 }
6029
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006030 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006031 HadAvailAttr = true;
6032 if (always_unavailable)
6033 *always_unavailable = 1;
6034 if (unavailable_message) {
6035 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6036 }
6037 continue;
6038 }
6039
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006040 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006041 HadAvailAttr = true;
6042 if (N < availability_size) {
6043 availability[N].Platform
6044 = cxstring::createDup(Avail->getPlatform()->getName());
6045 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6046 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6047 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6048 availability[N].Unavailable = Avail->getUnavailable();
6049 availability[N].Message = cxstring::createDup(Avail->getMessage());
6050 }
6051 ++N;
6052 }
6053 }
6054
6055 if (!HadAvailAttr)
6056 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6057 return getCursorPlatformAvailabilityForDecl(
6058 cast<Decl>(EnumConst->getDeclContext()),
6059 always_deprecated,
6060 deprecated_message,
6061 always_unavailable,
6062 unavailable_message,
6063 availability,
6064 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006065
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006066 return N;
6067}
6068
Guy Benyei11169dd2012-12-18 14:30:41 +00006069int clang_getCursorPlatformAvailability(CXCursor cursor,
6070 int *always_deprecated,
6071 CXString *deprecated_message,
6072 int *always_unavailable,
6073 CXString *unavailable_message,
6074 CXPlatformAvailability *availability,
6075 int availability_size) {
6076 if (always_deprecated)
6077 *always_deprecated = 0;
6078 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006079 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006080 if (always_unavailable)
6081 *always_unavailable = 0;
6082 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006083 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006084
Guy Benyei11169dd2012-12-18 14:30:41 +00006085 if (!clang_isDeclaration(cursor.kind))
6086 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006087
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006088 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006089 if (!D)
6090 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006091
6092 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6093 deprecated_message,
6094 always_unavailable,
6095 unavailable_message,
6096 availability,
6097 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006098}
6099
6100void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6101 clang_disposeString(availability->Platform);
6102 clang_disposeString(availability->Message);
6103}
6104
6105CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6106 if (clang_isDeclaration(cursor.kind))
6107 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6108
6109 return CXLanguage_Invalid;
6110}
6111
6112 /// \brief If the given cursor is the "templated" declaration
6113 /// descibing a class or function template, return the class or
6114 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006115static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006116 if (!D)
6117 return 0;
6118
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006119 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006120 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6121 return FunTmpl;
6122
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006123 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006124 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6125 return ClassTmpl;
6126
6127 return D;
6128}
6129
6130CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6131 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006132 if (const Decl *D = getCursorDecl(cursor)) {
6133 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006134 if (!DC)
6135 return clang_getNullCursor();
6136
6137 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6138 getCursorTU(cursor));
6139 }
6140 }
6141
6142 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006143 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006144 return MakeCXCursor(D, getCursorTU(cursor));
6145 }
6146
6147 return clang_getNullCursor();
6148}
6149
6150CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6151 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006152 if (const Decl *D = getCursorDecl(cursor)) {
6153 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006154 if (!DC)
6155 return clang_getNullCursor();
6156
6157 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6158 getCursorTU(cursor));
6159 }
6160 }
6161
6162 // FIXME: Note that we can't easily compute the lexical context of a
6163 // statement or expression, so we return nothing.
6164 return clang_getNullCursor();
6165}
6166
6167CXFile clang_getIncludedFile(CXCursor cursor) {
6168 if (cursor.kind != CXCursor_InclusionDirective)
6169 return 0;
6170
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006171 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006172 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006173}
6174
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006175unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6176 if (C.kind != CXCursor_ObjCPropertyDecl)
6177 return CXObjCPropertyAttr_noattr;
6178
6179 unsigned Result = CXObjCPropertyAttr_noattr;
6180 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6181 ObjCPropertyDecl::PropertyAttributeKind Attr =
6182 PD->getPropertyAttributesAsWritten();
6183
6184#define SET_CXOBJCPROP_ATTR(A) \
6185 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6186 Result |= CXObjCPropertyAttr_##A
6187 SET_CXOBJCPROP_ATTR(readonly);
6188 SET_CXOBJCPROP_ATTR(getter);
6189 SET_CXOBJCPROP_ATTR(assign);
6190 SET_CXOBJCPROP_ATTR(readwrite);
6191 SET_CXOBJCPROP_ATTR(retain);
6192 SET_CXOBJCPROP_ATTR(copy);
6193 SET_CXOBJCPROP_ATTR(nonatomic);
6194 SET_CXOBJCPROP_ATTR(setter);
6195 SET_CXOBJCPROP_ATTR(atomic);
6196 SET_CXOBJCPROP_ATTR(weak);
6197 SET_CXOBJCPROP_ATTR(strong);
6198 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6199#undef SET_CXOBJCPROP_ATTR
6200
6201 return Result;
6202}
6203
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006204unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6205 if (!clang_isDeclaration(C.kind))
6206 return CXObjCDeclQualifier_None;
6207
6208 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6209 const Decl *D = getCursorDecl(C);
6210 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6211 QT = MD->getObjCDeclQualifier();
6212 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6213 QT = PD->getObjCDeclQualifier();
6214 if (QT == Decl::OBJC_TQ_None)
6215 return CXObjCDeclQualifier_None;
6216
6217 unsigned Result = CXObjCDeclQualifier_None;
6218 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6219 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6220 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6221 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6222 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6223 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6224
6225 return Result;
6226}
6227
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006228unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6229 if (!clang_isDeclaration(C.kind))
6230 return 0;
6231
6232 const Decl *D = getCursorDecl(C);
6233 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6234 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6235 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6236 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6237
6238 return 0;
6239}
6240
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006241unsigned clang_Cursor_isVariadic(CXCursor C) {
6242 if (!clang_isDeclaration(C.kind))
6243 return 0;
6244
6245 const Decl *D = getCursorDecl(C);
6246 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6247 return FD->isVariadic();
6248 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6249 return MD->isVariadic();
6250
6251 return 0;
6252}
6253
Guy Benyei11169dd2012-12-18 14:30:41 +00006254CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6255 if (!clang_isDeclaration(C.kind))
6256 return clang_getNullRange();
6257
6258 const Decl *D = getCursorDecl(C);
6259 ASTContext &Context = getCursorContext(C);
6260 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6261 if (!RC)
6262 return clang_getNullRange();
6263
6264 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6265}
6266
6267CXString clang_Cursor_getRawCommentText(CXCursor C) {
6268 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006269 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006270
6271 const Decl *D = getCursorDecl(C);
6272 ASTContext &Context = getCursorContext(C);
6273 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6274 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6275 StringRef();
6276
6277 // Don't duplicate the string because RawText points directly into source
6278 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006279 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006280}
6281
6282CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6283 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006284 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006285
6286 const Decl *D = getCursorDecl(C);
6287 const ASTContext &Context = getCursorContext(C);
6288 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6289
6290 if (RC) {
6291 StringRef BriefText = RC->getBriefText(Context);
6292
6293 // Don't duplicate the string because RawComment ensures that this memory
6294 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006295 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006296 }
6297
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006298 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006299}
6300
6301CXComment clang_Cursor_getParsedComment(CXCursor C) {
6302 if (!clang_isDeclaration(C.kind))
6303 return cxcomment::createCXComment(NULL, NULL);
6304
6305 const Decl *D = getCursorDecl(C);
6306 const ASTContext &Context = getCursorContext(C);
6307 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6308
6309 return cxcomment::createCXComment(FC, getCursorTU(C));
6310}
6311
6312CXModule clang_Cursor_getModule(CXCursor C) {
6313 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006314 if (const ImportDecl *ImportD =
6315 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006316 return ImportD->getImportedModule();
6317 }
6318
6319 return 0;
6320}
6321
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006322CXFile clang_Module_getASTFile(CXModule CXMod) {
6323 if (!CXMod)
6324 return 0;
6325 Module *Mod = static_cast<Module*>(CXMod);
6326 return const_cast<FileEntry *>(Mod->getASTFile());
6327}
6328
Guy Benyei11169dd2012-12-18 14:30:41 +00006329CXModule clang_Module_getParent(CXModule CXMod) {
6330 if (!CXMod)
6331 return 0;
6332 Module *Mod = static_cast<Module*>(CXMod);
6333 return Mod->Parent;
6334}
6335
6336CXString clang_Module_getName(CXModule CXMod) {
6337 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006338 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006339 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006340 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006341}
6342
6343CXString clang_Module_getFullName(CXModule CXMod) {
6344 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006345 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006346 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006347 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006348}
6349
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006350unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6351 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006352 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006353 LOG_BAD_TU(TU);
6354 return 0;
6355 }
6356 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006357 return 0;
6358 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006359 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6360 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6361 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006362}
6363
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006364CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6365 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006366 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006367 LOG_BAD_TU(TU);
6368 return 0;
6369 }
6370 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006371 return 0;
6372 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006373 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006374
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006375 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6376 if (Index < TopHeaders.size())
6377 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006378
6379 return 0;
6380}
6381
6382} // end: extern "C"
6383
6384//===----------------------------------------------------------------------===//
6385// C++ AST instrospection.
6386//===----------------------------------------------------------------------===//
6387
6388extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006389unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6390 if (!clang_isDeclaration(C.kind))
6391 return 0;
6392
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006393 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006394 const CXXMethodDecl *Method =
6395 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006396 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6397}
6398
Guy Benyei11169dd2012-12-18 14:30:41 +00006399unsigned clang_CXXMethod_isStatic(CXCursor C) {
6400 if (!clang_isDeclaration(C.kind))
6401 return 0;
6402
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006403 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006404 const CXXMethodDecl *Method =
6405 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006406 return (Method && Method->isStatic()) ? 1 : 0;
6407}
6408
6409unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6410 if (!clang_isDeclaration(C.kind))
6411 return 0;
6412
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006413 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006414 const CXXMethodDecl *Method =
6415 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006416 return (Method && Method->isVirtual()) ? 1 : 0;
6417}
6418} // end: extern "C"
6419
6420//===----------------------------------------------------------------------===//
6421// Attribute introspection.
6422//===----------------------------------------------------------------------===//
6423
6424extern "C" {
6425CXType clang_getIBOutletCollectionType(CXCursor C) {
6426 if (C.kind != CXCursor_IBOutletCollectionAttr)
6427 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6428
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006429 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006430 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6431
6432 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6433}
6434} // end: extern "C"
6435
6436//===----------------------------------------------------------------------===//
6437// Inspecting memory usage.
6438//===----------------------------------------------------------------------===//
6439
6440typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6441
6442static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6443 enum CXTUResourceUsageKind k,
6444 unsigned long amount) {
6445 CXTUResourceUsageEntry entry = { k, amount };
6446 entries.push_back(entry);
6447}
6448
6449extern "C" {
6450
6451const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6452 const char *str = "";
6453 switch (kind) {
6454 case CXTUResourceUsage_AST:
6455 str = "ASTContext: expressions, declarations, and types";
6456 break;
6457 case CXTUResourceUsage_Identifiers:
6458 str = "ASTContext: identifiers";
6459 break;
6460 case CXTUResourceUsage_Selectors:
6461 str = "ASTContext: selectors";
6462 break;
6463 case CXTUResourceUsage_GlobalCompletionResults:
6464 str = "Code completion: cached global results";
6465 break;
6466 case CXTUResourceUsage_SourceManagerContentCache:
6467 str = "SourceManager: content cache allocator";
6468 break;
6469 case CXTUResourceUsage_AST_SideTables:
6470 str = "ASTContext: side tables";
6471 break;
6472 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6473 str = "SourceManager: malloc'ed memory buffers";
6474 break;
6475 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6476 str = "SourceManager: mmap'ed memory buffers";
6477 break;
6478 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6479 str = "ExternalASTSource: malloc'ed memory buffers";
6480 break;
6481 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6482 str = "ExternalASTSource: mmap'ed memory buffers";
6483 break;
6484 case CXTUResourceUsage_Preprocessor:
6485 str = "Preprocessor: malloc'ed memory";
6486 break;
6487 case CXTUResourceUsage_PreprocessingRecord:
6488 str = "Preprocessor: PreprocessingRecord";
6489 break;
6490 case CXTUResourceUsage_SourceManager_DataStructures:
6491 str = "SourceManager: data structures and tables";
6492 break;
6493 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6494 str = "Preprocessor: header search tables";
6495 break;
6496 }
6497 return str;
6498}
6499
6500CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006501 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006502 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006503 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6504 return usage;
6505 }
6506
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006507 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006508 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006509 ASTContext &astContext = astUnit->getASTContext();
6510
6511 // How much memory is used by AST nodes and types?
6512 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6513 (unsigned long) astContext.getASTAllocatedMemory());
6514
6515 // How much memory is used by identifiers?
6516 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6517 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6518
6519 // How much memory is used for selectors?
6520 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6521 (unsigned long) astContext.Selectors.getTotalMemory());
6522
6523 // How much memory is used by ASTContext's side tables?
6524 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6525 (unsigned long) astContext.getSideTableAllocatedMemory());
6526
6527 // How much memory is used for caching global code completion results?
6528 unsigned long completionBytes = 0;
6529 if (GlobalCodeCompletionAllocator *completionAllocator =
6530 astUnit->getCachedCompletionAllocator().getPtr()) {
6531 completionBytes = completionAllocator->getTotalMemory();
6532 }
6533 createCXTUResourceUsageEntry(*entries,
6534 CXTUResourceUsage_GlobalCompletionResults,
6535 completionBytes);
6536
6537 // How much memory is being used by SourceManager's content cache?
6538 createCXTUResourceUsageEntry(*entries,
6539 CXTUResourceUsage_SourceManagerContentCache,
6540 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6541
6542 // How much memory is being used by the MemoryBuffer's in SourceManager?
6543 const SourceManager::MemoryBufferSizes &srcBufs =
6544 astUnit->getSourceManager().getMemoryBufferSizes();
6545
6546 createCXTUResourceUsageEntry(*entries,
6547 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6548 (unsigned long) srcBufs.malloc_bytes);
6549 createCXTUResourceUsageEntry(*entries,
6550 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6551 (unsigned long) srcBufs.mmap_bytes);
6552 createCXTUResourceUsageEntry(*entries,
6553 CXTUResourceUsage_SourceManager_DataStructures,
6554 (unsigned long) astContext.getSourceManager()
6555 .getDataStructureSizes());
6556
6557 // How much memory is being used by the ExternalASTSource?
6558 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6559 const ExternalASTSource::MemoryBufferSizes &sizes =
6560 esrc->getMemoryBufferSizes();
6561
6562 createCXTUResourceUsageEntry(*entries,
6563 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6564 (unsigned long) sizes.malloc_bytes);
6565 createCXTUResourceUsageEntry(*entries,
6566 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6567 (unsigned long) sizes.mmap_bytes);
6568 }
6569
6570 // How much memory is being used by the Preprocessor?
6571 Preprocessor &pp = astUnit->getPreprocessor();
6572 createCXTUResourceUsageEntry(*entries,
6573 CXTUResourceUsage_Preprocessor,
6574 pp.getTotalMemory());
6575
6576 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6577 createCXTUResourceUsageEntry(*entries,
6578 CXTUResourceUsage_PreprocessingRecord,
6579 pRec->getTotalMemory());
6580 }
6581
6582 createCXTUResourceUsageEntry(*entries,
6583 CXTUResourceUsage_Preprocessor_HeaderSearch,
6584 pp.getHeaderSearchInfo().getTotalMemory());
6585
6586 CXTUResourceUsage usage = { (void*) entries.get(),
6587 (unsigned) entries->size(),
6588 entries->size() ? &(*entries)[0] : 0 };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006589 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006590 return usage;
6591}
6592
6593void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6594 if (usage.data)
6595 delete (MemUsageEntries*) usage.data;
6596}
6597
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006598CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6599 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006600 skipped->count = 0;
6601 skipped->ranges = 0;
6602
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006603 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006604 LOG_BAD_TU(TU);
6605 return skipped;
6606 }
6607
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006608 if (!file)
6609 return skipped;
6610
6611 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6612 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6613 if (!ppRec)
6614 return skipped;
6615
6616 ASTContext &Ctx = astUnit->getASTContext();
6617 SourceManager &sm = Ctx.getSourceManager();
6618 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6619 FileID wantedFileID = sm.translateFile(fileEntry);
6620
6621 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6622 std::vector<SourceRange> wantedRanges;
6623 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6624 i != ei; ++i) {
6625 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6626 wantedRanges.push_back(*i);
6627 }
6628
6629 skipped->count = wantedRanges.size();
6630 skipped->ranges = new CXSourceRange[skipped->count];
6631 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6632 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6633
6634 return skipped;
6635}
6636
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006637void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6638 if (ranges) {
6639 delete[] ranges->ranges;
6640 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006641 }
6642}
6643
Guy Benyei11169dd2012-12-18 14:30:41 +00006644} // end extern "C"
6645
6646void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6647 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6648 for (unsigned I = 0; I != Usage.numEntries; ++I)
6649 fprintf(stderr, " %s: %lu\n",
6650 clang_getTUResourceUsageName(Usage.entries[I].kind),
6651 Usage.entries[I].amount);
6652
6653 clang_disposeCXTUResourceUsage(Usage);
6654}
6655
6656//===----------------------------------------------------------------------===//
6657// Misc. utility functions.
6658//===----------------------------------------------------------------------===//
6659
6660/// Default to using an 8 MB stack size on "safety" threads.
6661static unsigned SafetyStackThreadSize = 8 << 20;
6662
6663namespace clang {
6664
6665bool RunSafely(llvm::CrashRecoveryContext &CRC,
6666 void (*Fn)(void*), void *UserData,
6667 unsigned Size) {
6668 if (!Size)
6669 Size = GetSafetyThreadStackSize();
6670 if (Size)
6671 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6672 return CRC.RunSafely(Fn, UserData);
6673}
6674
6675unsigned GetSafetyThreadStackSize() {
6676 return SafetyStackThreadSize;
6677}
6678
6679void SetSafetyThreadStackSize(unsigned Value) {
6680 SafetyStackThreadSize = Value;
6681}
6682
6683}
6684
6685void clang::setThreadBackgroundPriority() {
6686 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6687 return;
6688
6689 // FIXME: Move to llvm/Support and make it cross-platform.
6690#ifdef __APPLE__
6691 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6692#endif
6693}
6694
6695void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6696 if (!Unit)
6697 return;
6698
6699 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6700 DEnd = Unit->stored_diag_end();
6701 D != DEnd; ++D) {
6702 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6703 CXString Msg = clang_formatDiagnostic(&Diag,
6704 clang_defaultDiagnosticDisplayOptions());
6705 fprintf(stderr, "%s\n", clang_getCString(Msg));
6706 clang_disposeString(Msg);
6707 }
6708#ifdef LLVM_ON_WIN32
6709 // On Windows, force a flush, since there may be multiple copies of
6710 // stderr and stdout in the file system, all with different buffers
6711 // but writing to the same device.
6712 fflush(stderr);
6713#endif
6714}
6715
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006716MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6717 SourceLocation MacroDefLoc,
6718 CXTranslationUnit TU){
6719 if (MacroDefLoc.isInvalid() || !TU)
6720 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006721 if (!II.hadMacroDefinition())
6722 return 0;
6723
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006724 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006725 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006726 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006727 if (MD) {
6728 for (MacroDirective::DefInfo
6729 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6730 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6731 return Def.getMacroInfo();
6732 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006733 }
6734
6735 return 0;
6736}
6737
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006738const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6739 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006740 if (!MacroDef || !TU)
6741 return 0;
6742 const IdentifierInfo *II = MacroDef->getName();
6743 if (!II)
6744 return 0;
6745
6746 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6747}
6748
6749MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6750 const Token &Tok,
6751 CXTranslationUnit TU) {
6752 if (!MI || !TU)
6753 return 0;
6754 if (Tok.isNot(tok::raw_identifier))
6755 return 0;
6756
6757 if (MI->getNumTokens() == 0)
6758 return 0;
6759 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6760 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006761 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006762
6763 // Check that the token is inside the definition and not its argument list.
6764 SourceManager &SM = Unit->getSourceManager();
6765 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6766 return 0;
6767 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6768 return 0;
6769
6770 Preprocessor &PP = Unit->getPreprocessor();
6771 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6772 if (!PPRec)
6773 return 0;
6774
6775 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6776 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6777 if (!II.hadMacroDefinition())
6778 return 0;
6779
6780 // Check that the identifier is not one of the macro arguments.
6781 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6782 return 0;
6783
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006784 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6785 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006786 return 0;
6787
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006788 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006789}
6790
6791MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6792 SourceLocation Loc,
6793 CXTranslationUnit TU) {
6794 if (Loc.isInvalid() || !MI || !TU)
6795 return 0;
6796
6797 if (MI->getNumTokens() == 0)
6798 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006799 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006800 Preprocessor &PP = Unit->getPreprocessor();
6801 if (!PP.getPreprocessingRecord())
6802 return 0;
6803 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6804 Token Tok;
6805 if (PP.getRawToken(Loc, Tok))
6806 return 0;
6807
6808 return checkForMacroInMacroDefinition(MI, Tok, TU);
6809}
6810
Guy Benyei11169dd2012-12-18 14:30:41 +00006811extern "C" {
6812
6813CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006814 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006815}
6816
6817} // end: extern "C"
6818
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006819Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6820 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006821 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006822 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006823 if (Unit->isMainFileAST())
6824 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006825 return *this;
6826 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006827 } else {
6828 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006829 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006830 return *this;
6831}
6832
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006833Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6834 *this << FE->getName();
6835 return *this;
6836}
6837
6838Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6839 CXString cursorName = clang_getCursorDisplayName(cursor);
6840 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6841 clang_disposeString(cursorName);
6842 return *this;
6843}
6844
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006845Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6846 CXFile File;
6847 unsigned Line, Column;
6848 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6849 CXString FileName = clang_getFileName(File);
6850 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6851 clang_disposeString(FileName);
6852 return *this;
6853}
6854
6855Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6856 CXSourceLocation BLoc = clang_getRangeStart(range);
6857 CXSourceLocation ELoc = clang_getRangeEnd(range);
6858
6859 CXFile BFile;
6860 unsigned BLine, BColumn;
6861 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6862
6863 CXFile EFile;
6864 unsigned ELine, EColumn;
6865 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6866
6867 CXString BFileName = clang_getFileName(BFile);
6868 if (BFile == EFile) {
6869 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6870 BLine, BColumn, ELine, EColumn);
6871 } else {
6872 CXString EFileName = clang_getFileName(EFile);
6873 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6874 BLine, BColumn)
6875 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6876 ELine, EColumn);
6877 clang_disposeString(EFileName);
6878 }
6879 clang_disposeString(BFileName);
6880 return *this;
6881}
6882
6883Logger &cxindex::Logger::operator<<(CXString Str) {
6884 *this << clang_getCString(Str);
6885 return *this;
6886}
6887
6888Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6889 LogOS << Fmt;
6890 return *this;
6891}
6892
6893cxindex::Logger::~Logger() {
6894 LogOS.flush();
6895
6896 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6897
6898 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6899
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006900 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006901 OS << "[libclang:" << Name << ':';
6902
6903 // FIXME: Portability.
6904#if HAVE_PTHREAD_H && __APPLE__
6905 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6906 OS << tid << ':';
6907#endif
6908
6909 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6910 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6911 OS << Msg.str() << '\n';
6912
6913 if (Trace) {
6914 llvm::sys::PrintStackTrace(stderr);
6915 OS << "--------------------------------------------------\n";
6916 }
6917}