blob: 6646200934eb11965969660c948e5ef092ab6ef5 [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;
815 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
816 IEnd = Constructor->init_end();
817 I != IEnd; ++I) {
818 if (!(*I)->isWritten())
819 continue;
820
821 WrittenInits.push_back(*I);
822 }
823
824 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000825 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
826 &CompareCXXCtorInitializers);
827
Guy Benyei11169dd2012-12-18 14:30:41 +0000828 // Visit the initializers in source order
829 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
830 CXXCtorInitializer *Init = WrittenInits[I];
831 if (Init->isAnyMemberInitializer()) {
832 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
833 Init->getMemberLocation(), TU)))
834 return true;
835 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
836 if (Visit(TInfo->getTypeLoc()))
837 return true;
838 }
839
840 // Visit the initializer value.
841 if (Expr *Initializer = Init->getInit())
842 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
843 return true;
844 }
845 }
846
847 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
848 return true;
849 }
850
851 return false;
852}
853
854bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
855 if (VisitDeclaratorDecl(D))
856 return true;
857
858 if (Expr *BitWidth = D->getBitWidth())
859 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
860
861 return false;
862}
863
864bool CursorVisitor::VisitVarDecl(VarDecl *D) {
865 if (VisitDeclaratorDecl(D))
866 return true;
867
868 if (Expr *Init = D->getInit())
869 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
870
871 return false;
872}
873
874bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
875 if (VisitDeclaratorDecl(D))
876 return true;
877
878 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
879 if (Expr *DefArg = D->getDefaultArgument())
880 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
881
882 return false;
883}
884
885bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
886 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
887 // before visiting these template parameters.
888 if (VisitTemplateParameters(D->getTemplateParameters()))
889 return true;
890
891 return VisitFunctionDecl(D->getTemplatedDecl());
892}
893
894bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
895 // FIXME: Visit the "outer" template parameter lists on the TagDecl
896 // before visiting these template parameters.
897 if (VisitTemplateParameters(D->getTemplateParameters()))
898 return true;
899
900 return VisitCXXRecordDecl(D->getTemplatedDecl());
901}
902
903bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
904 if (VisitTemplateParameters(D->getTemplateParameters()))
905 return true;
906
907 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
908 VisitTemplateArgumentLoc(D->getDefaultArgument()))
909 return true;
910
911 return false;
912}
913
914bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000915 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000916 if (Visit(TSInfo->getTypeLoc()))
917 return true;
918
Aaron Ballman43b68be2014-03-07 17:50:17 +0000919 for (const auto *P : ND->params()) {
920 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000921 return true;
922 }
923
924 if (ND->isThisDeclarationADefinition() &&
925 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
926 return true;
927
928 return false;
929}
930
931template <typename DeclIt>
932static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
933 SourceManager &SM, SourceLocation EndLoc,
934 SmallVectorImpl<Decl *> &Decls) {
935 DeclIt next = *DI_current;
936 while (++next != DE_current) {
937 Decl *D_next = *next;
938 if (!D_next)
939 break;
940 SourceLocation L = D_next->getLocStart();
941 if (!L.isValid())
942 break;
943 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
944 *DI_current = next;
945 Decls.push_back(D_next);
946 continue;
947 }
948 break;
949 }
950}
951
Guy Benyei11169dd2012-12-18 14:30:41 +0000952bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
953 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
954 // an @implementation can lexically contain Decls that are not properly
955 // nested in the AST. When we identify such cases, we need to retrofit
956 // this nesting here.
957 if (!DI_current && !FileDI_current)
958 return VisitDeclContext(D);
959
960 // Scan the Decls that immediately come after the container
961 // in the current DeclContext. If any fall within the
962 // container's lexical region, stash them into a vector
963 // for later processing.
964 SmallVector<Decl *, 24> DeclsInContainer;
965 SourceLocation EndLoc = D->getSourceRange().getEnd();
966 SourceManager &SM = AU->getSourceManager();
967 if (EndLoc.isValid()) {
968 if (DI_current) {
969 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
970 DeclsInContainer);
971 } else {
972 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
973 DeclsInContainer);
974 }
975 }
976
977 // The common case.
978 if (DeclsInContainer.empty())
979 return VisitDeclContext(D);
980
981 // Get all the Decls in the DeclContext, and sort them with the
982 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000983 for (auto *SubDecl : D->decls()) {
984 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
985 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000986 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000987 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000988 }
989
990 // Now sort the Decls so that they appear in lexical order.
991 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000992 [&SM](Decl *A, Decl *B) {
993 SourceLocation L_A = A->getLocStart();
994 SourceLocation L_B = B->getLocStart();
995 assert(L_A.isValid() && L_B.isValid());
996 return SM.isBeforeInTranslationUnit(L_A, L_B);
997 });
Guy Benyei11169dd2012-12-18 14:30:41 +0000998
999 // Now visit the decls.
1000 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1001 E = DeclsInContainer.end(); I != E; ++I) {
1002 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001003 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001004 if (!V.hasValue())
1005 continue;
1006 if (!V.getValue())
1007 return false;
1008 if (Visit(Cursor, true))
1009 return true;
1010 }
1011 return false;
1012}
1013
1014bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1015 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1016 TU)))
1017 return true;
1018
1019 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1020 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1021 E = ND->protocol_end(); I != E; ++I, ++PL)
1022 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1023 return true;
1024
1025 return VisitObjCContainerDecl(ND);
1026}
1027
1028bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1029 if (!PID->isThisDeclarationADefinition())
1030 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1031
1032 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1033 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1034 E = PID->protocol_end(); I != E; ++I, ++PL)
1035 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1036 return true;
1037
1038 return VisitObjCContainerDecl(PID);
1039}
1040
1041bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1042 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1043 return true;
1044
1045 // FIXME: This implements a workaround with @property declarations also being
1046 // installed in the DeclContext for the @interface. Eventually this code
1047 // should be removed.
1048 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1049 if (!CDecl || !CDecl->IsClassExtension())
1050 return false;
1051
1052 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1053 if (!ID)
1054 return false;
1055
1056 IdentifierInfo *PropertyId = PD->getIdentifier();
1057 ObjCPropertyDecl *prevDecl =
1058 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1059
1060 if (!prevDecl)
1061 return false;
1062
1063 // Visit synthesized methods since they will be skipped when visiting
1064 // the @interface.
1065 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1066 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1067 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1068 return true;
1069
1070 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1071 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1072 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1073 return true;
1074
1075 return false;
1076}
1077
1078bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1079 if (!D->isThisDeclarationADefinition()) {
1080 // Forward declaration is treated like a reference.
1081 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1082 }
1083
1084 // Issue callbacks for super class.
1085 if (D->getSuperClass() &&
1086 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1087 D->getSuperClassLoc(),
1088 TU)))
1089 return true;
1090
1091 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1092 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1093 E = D->protocol_end(); I != E; ++I, ++PL)
1094 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1095 return true;
1096
1097 return VisitObjCContainerDecl(D);
1098}
1099
1100bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1101 return VisitObjCContainerDecl(D);
1102}
1103
1104bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1105 // 'ID' could be null when dealing with invalid code.
1106 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1107 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1108 return true;
1109
1110 return VisitObjCImplDecl(D);
1111}
1112
1113bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1114#if 0
1115 // Issue callbacks for super class.
1116 // FIXME: No source location information!
1117 if (D->getSuperClass() &&
1118 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1119 D->getSuperClassLoc(),
1120 TU)))
1121 return true;
1122#endif
1123
1124 return VisitObjCImplDecl(D);
1125}
1126
1127bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1128 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1129 if (PD->isIvarNameSpecified())
1130 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1131
1132 return false;
1133}
1134
1135bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1136 return VisitDeclContext(D);
1137}
1138
1139bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1140 // Visit nested-name-specifier.
1141 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1142 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1143 return true;
1144
1145 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1146 D->getTargetNameLoc(), TU));
1147}
1148
1149bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1150 // Visit nested-name-specifier.
1151 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1152 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1153 return true;
1154 }
1155
1156 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1157 return true;
1158
1159 return VisitDeclarationNameInfo(D->getNameInfo());
1160}
1161
1162bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1163 // Visit nested-name-specifier.
1164 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1165 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1166 return true;
1167
1168 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1169 D->getIdentLocation(), TU));
1170}
1171
1172bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1173 // Visit nested-name-specifier.
1174 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1175 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1176 return true;
1177 }
1178
1179 return VisitDeclarationNameInfo(D->getNameInfo());
1180}
1181
1182bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1183 UnresolvedUsingTypenameDecl *D) {
1184 // Visit nested-name-specifier.
1185 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1186 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1187 return true;
1188
1189 return false;
1190}
1191
1192bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1193 switch (Name.getName().getNameKind()) {
1194 case clang::DeclarationName::Identifier:
1195 case clang::DeclarationName::CXXLiteralOperatorName:
1196 case clang::DeclarationName::CXXOperatorName:
1197 case clang::DeclarationName::CXXUsingDirective:
1198 return false;
1199
1200 case clang::DeclarationName::CXXConstructorName:
1201 case clang::DeclarationName::CXXDestructorName:
1202 case clang::DeclarationName::CXXConversionFunctionName:
1203 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1204 return Visit(TSInfo->getTypeLoc());
1205 return false;
1206
1207 case clang::DeclarationName::ObjCZeroArgSelector:
1208 case clang::DeclarationName::ObjCOneArgSelector:
1209 case clang::DeclarationName::ObjCMultiArgSelector:
1210 // FIXME: Per-identifier location info?
1211 return false;
1212 }
1213
1214 llvm_unreachable("Invalid DeclarationName::Kind!");
1215}
1216
1217bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1218 SourceRange Range) {
1219 // FIXME: This whole routine is a hack to work around the lack of proper
1220 // source information in nested-name-specifiers (PR5791). Since we do have
1221 // a beginning source location, we can visit the first component of the
1222 // nested-name-specifier, if it's a single-token component.
1223 if (!NNS)
1224 return false;
1225
1226 // Get the first component in the nested-name-specifier.
1227 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1228 NNS = Prefix;
1229
1230 switch (NNS->getKind()) {
1231 case NestedNameSpecifier::Namespace:
1232 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1233 TU));
1234
1235 case NestedNameSpecifier::NamespaceAlias:
1236 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1237 Range.getBegin(), TU));
1238
1239 case NestedNameSpecifier::TypeSpec: {
1240 // If the type has a form where we know that the beginning of the source
1241 // range matches up with a reference cursor. Visit the appropriate reference
1242 // cursor.
1243 const Type *T = NNS->getAsType();
1244 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1245 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1246 if (const TagType *Tag = dyn_cast<TagType>(T))
1247 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1248 if (const TemplateSpecializationType *TST
1249 = dyn_cast<TemplateSpecializationType>(T))
1250 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1251 break;
1252 }
1253
1254 case NestedNameSpecifier::TypeSpecWithTemplate:
1255 case NestedNameSpecifier::Global:
1256 case NestedNameSpecifier::Identifier:
1257 break;
1258 }
1259
1260 return false;
1261}
1262
1263bool
1264CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1265 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1266 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1267 Qualifiers.push_back(Qualifier);
1268
1269 while (!Qualifiers.empty()) {
1270 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1271 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1272 switch (NNS->getKind()) {
1273 case NestedNameSpecifier::Namespace:
1274 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1275 Q.getLocalBeginLoc(),
1276 TU)))
1277 return true;
1278
1279 break;
1280
1281 case NestedNameSpecifier::NamespaceAlias:
1282 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1283 Q.getLocalBeginLoc(),
1284 TU)))
1285 return true;
1286
1287 break;
1288
1289 case NestedNameSpecifier::TypeSpec:
1290 case NestedNameSpecifier::TypeSpecWithTemplate:
1291 if (Visit(Q.getTypeLoc()))
1292 return true;
1293
1294 break;
1295
1296 case NestedNameSpecifier::Global:
1297 case NestedNameSpecifier::Identifier:
1298 break;
1299 }
1300 }
1301
1302 return false;
1303}
1304
1305bool CursorVisitor::VisitTemplateParameters(
1306 const TemplateParameterList *Params) {
1307 if (!Params)
1308 return false;
1309
1310 for (TemplateParameterList::const_iterator P = Params->begin(),
1311 PEnd = Params->end();
1312 P != PEnd; ++P) {
1313 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1314 return true;
1315 }
1316
1317 return false;
1318}
1319
1320bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1321 switch (Name.getKind()) {
1322 case TemplateName::Template:
1323 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1324
1325 case TemplateName::OverloadedTemplate:
1326 // Visit the overloaded template set.
1327 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1328 return true;
1329
1330 return false;
1331
1332 case TemplateName::DependentTemplate:
1333 // FIXME: Visit nested-name-specifier.
1334 return false;
1335
1336 case TemplateName::QualifiedTemplate:
1337 // FIXME: Visit nested-name-specifier.
1338 return Visit(MakeCursorTemplateRef(
1339 Name.getAsQualifiedTemplateName()->getDecl(),
1340 Loc, TU));
1341
1342 case TemplateName::SubstTemplateTemplateParm:
1343 return Visit(MakeCursorTemplateRef(
1344 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1345 Loc, TU));
1346
1347 case TemplateName::SubstTemplateTemplateParmPack:
1348 return Visit(MakeCursorTemplateRef(
1349 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1350 Loc, TU));
1351 }
1352
1353 llvm_unreachable("Invalid TemplateName::Kind!");
1354}
1355
1356bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1357 switch (TAL.getArgument().getKind()) {
1358 case TemplateArgument::Null:
1359 case TemplateArgument::Integral:
1360 case TemplateArgument::Pack:
1361 return false;
1362
1363 case TemplateArgument::Type:
1364 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1365 return Visit(TSInfo->getTypeLoc());
1366 return false;
1367
1368 case TemplateArgument::Declaration:
1369 if (Expr *E = TAL.getSourceDeclExpression())
1370 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1371 return false;
1372
1373 case TemplateArgument::NullPtr:
1374 if (Expr *E = TAL.getSourceNullPtrExpression())
1375 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1376 return false;
1377
1378 case TemplateArgument::Expression:
1379 if (Expr *E = TAL.getSourceExpression())
1380 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1381 return false;
1382
1383 case TemplateArgument::Template:
1384 case TemplateArgument::TemplateExpansion:
1385 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1386 return true;
1387
1388 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1389 TAL.getTemplateNameLoc());
1390 }
1391
1392 llvm_unreachable("Invalid TemplateArgument::Kind!");
1393}
1394
1395bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1396 return VisitDeclContext(D);
1397}
1398
1399bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1400 return Visit(TL.getUnqualifiedLoc());
1401}
1402
1403bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1404 ASTContext &Context = AU->getASTContext();
1405
1406 // Some builtin types (such as Objective-C's "id", "sel", and
1407 // "Class") have associated declarations. Create cursors for those.
1408 QualType VisitType;
1409 switch (TL.getTypePtr()->getKind()) {
1410
1411 case BuiltinType::Void:
1412 case BuiltinType::NullPtr:
1413 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001414 case BuiltinType::OCLImage1d:
1415 case BuiltinType::OCLImage1dArray:
1416 case BuiltinType::OCLImage1dBuffer:
1417 case BuiltinType::OCLImage2d:
1418 case BuiltinType::OCLImage2dArray:
1419 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001420 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001421 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001422#define BUILTIN_TYPE(Id, SingletonId)
1423#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1424#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1425#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1426#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1427#include "clang/AST/BuiltinTypes.def"
1428 break;
1429
1430 case BuiltinType::ObjCId:
1431 VisitType = Context.getObjCIdType();
1432 break;
1433
1434 case BuiltinType::ObjCClass:
1435 VisitType = Context.getObjCClassType();
1436 break;
1437
1438 case BuiltinType::ObjCSel:
1439 VisitType = Context.getObjCSelType();
1440 break;
1441 }
1442
1443 if (!VisitType.isNull()) {
1444 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1445 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1446 TU));
1447 }
1448
1449 return false;
1450}
1451
1452bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1453 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1454}
1455
1456bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1457 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1458}
1459
1460bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1461 if (TL.isDefinition())
1462 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1463
1464 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1465}
1466
1467bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1468 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1469}
1470
1471bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1472 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1473 return true;
1474
1475 return false;
1476}
1477
1478bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1479 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1480 return true;
1481
1482 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1483 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1484 TU)))
1485 return true;
1486 }
1487
1488 return false;
1489}
1490
1491bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1492 return Visit(TL.getPointeeLoc());
1493}
1494
1495bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1496 return Visit(TL.getInnerLoc());
1497}
1498
1499bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1500 return Visit(TL.getPointeeLoc());
1501}
1502
1503bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1504 return Visit(TL.getPointeeLoc());
1505}
1506
1507bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1508 return Visit(TL.getPointeeLoc());
1509}
1510
1511bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1512 return Visit(TL.getPointeeLoc());
1513}
1514
1515bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1516 return Visit(TL.getPointeeLoc());
1517}
1518
1519bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1520 return Visit(TL.getModifiedLoc());
1521}
1522
1523bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1524 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001525 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001526 return true;
1527
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001528 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1529 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001530 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1531 return true;
1532
1533 return false;
1534}
1535
1536bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1537 if (Visit(TL.getElementLoc()))
1538 return true;
1539
1540 if (Expr *Size = TL.getSizeExpr())
1541 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1542
1543 return false;
1544}
1545
Reid Kleckner8a365022013-06-24 17:51:48 +00001546bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1547 return Visit(TL.getOriginalLoc());
1548}
1549
Reid Kleckner0503a872013-12-05 01:23:43 +00001550bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1551 return Visit(TL.getOriginalLoc());
1552}
1553
Guy Benyei11169dd2012-12-18 14:30:41 +00001554bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1555 TemplateSpecializationTypeLoc TL) {
1556 // Visit the template name.
1557 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1558 TL.getTemplateNameLoc()))
1559 return true;
1560
1561 // Visit the template arguments.
1562 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1563 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1564 return true;
1565
1566 return false;
1567}
1568
1569bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1570 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1571}
1572
1573bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1574 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1575 return Visit(TSInfo->getTypeLoc());
1576
1577 return false;
1578}
1579
1580bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1581 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1582 return Visit(TSInfo->getTypeLoc());
1583
1584 return false;
1585}
1586
1587bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1588 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1589 return true;
1590
1591 return false;
1592}
1593
1594bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1595 DependentTemplateSpecializationTypeLoc TL) {
1596 // Visit the nested-name-specifier, if there is one.
1597 if (TL.getQualifierLoc() &&
1598 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1599 return true;
1600
1601 // Visit the template arguments.
1602 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1603 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1604 return true;
1605
1606 return false;
1607}
1608
1609bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1610 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1611 return true;
1612
1613 return Visit(TL.getNamedTypeLoc());
1614}
1615
1616bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1617 return Visit(TL.getPatternLoc());
1618}
1619
1620bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1621 if (Expr *E = TL.getUnderlyingExpr())
1622 return Visit(MakeCXCursor(E, StmtParent, TU));
1623
1624 return false;
1625}
1626
1627bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1628 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1629}
1630
1631bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1632 return Visit(TL.getValueLoc());
1633}
1634
1635#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1636bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1637 return Visit##PARENT##Loc(TL); \
1638}
1639
1640DEFAULT_TYPELOC_IMPL(Complex, Type)
1641DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1642DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1643DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1644DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1645DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1646DEFAULT_TYPELOC_IMPL(Vector, Type)
1647DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1648DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1649DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1650DEFAULT_TYPELOC_IMPL(Record, TagType)
1651DEFAULT_TYPELOC_IMPL(Enum, TagType)
1652DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1653DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1654DEFAULT_TYPELOC_IMPL(Auto, Type)
1655
1656bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1657 // Visit the nested-name-specifier, if present.
1658 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1659 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1660 return true;
1661
1662 if (D->isCompleteDefinition()) {
1663 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1664 E = D->bases_end(); I != E; ++I) {
1665 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1666 return true;
1667 }
1668 }
1669
1670 return VisitTagDecl(D);
1671}
1672
1673bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001674 for (const auto *I : D->attrs())
1675 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001676 return true;
1677
1678 return false;
1679}
1680
1681//===----------------------------------------------------------------------===//
1682// Data-recursive visitor methods.
1683//===----------------------------------------------------------------------===//
1684
1685namespace {
1686#define DEF_JOB(NAME, DATA, KIND)\
1687class NAME : public VisitorJob {\
1688public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001689 NAME(const DATA *d, CXCursor parent) : \
1690 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001691 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001692 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001693};
1694
1695DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1696DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1697DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1698DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1699DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1700 ExplicitTemplateArgsVisitKind)
1701DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1702DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1703DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1704#undef DEF_JOB
1705
1706class DeclVisit : public VisitorJob {
1707public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001708 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001709 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001710 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001711 static bool classof(const VisitorJob *VJ) {
1712 return VJ->getKind() == DeclVisitKind;
1713 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001714 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001715 bool isFirst() const { return data[1] ? true : false; }
1716};
1717class TypeLocVisit : public VisitorJob {
1718public:
1719 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1720 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1721 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1722
1723 static bool classof(const VisitorJob *VJ) {
1724 return VJ->getKind() == TypeLocVisitKind;
1725 }
1726
1727 TypeLoc get() const {
1728 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001729 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001730 }
1731};
1732
1733class LabelRefVisit : public VisitorJob {
1734public:
1735 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1736 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1737 labelLoc.getPtrEncoding()) {}
1738
1739 static bool classof(const VisitorJob *VJ) {
1740 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1741 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001742 const LabelDecl *get() const {
1743 return static_cast<const LabelDecl *>(data[0]);
1744 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001745 SourceLocation getLoc() const {
1746 return SourceLocation::getFromPtrEncoding(data[1]); }
1747};
1748
1749class NestedNameSpecifierLocVisit : public VisitorJob {
1750public:
1751 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1752 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1753 Qualifier.getNestedNameSpecifier(),
1754 Qualifier.getOpaqueData()) { }
1755
1756 static bool classof(const VisitorJob *VJ) {
1757 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1758 }
1759
1760 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001761 return NestedNameSpecifierLoc(
1762 const_cast<NestedNameSpecifier *>(
1763 static_cast<const NestedNameSpecifier *>(data[0])),
1764 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001765 }
1766};
1767
1768class DeclarationNameInfoVisit : public VisitorJob {
1769public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001770 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001771 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001772 static bool classof(const VisitorJob *VJ) {
1773 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1774 }
1775 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001776 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001777 switch (S->getStmtClass()) {
1778 default:
1779 llvm_unreachable("Unhandled Stmt");
1780 case clang::Stmt::MSDependentExistsStmtClass:
1781 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1782 case Stmt::CXXDependentScopeMemberExprClass:
1783 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1784 case Stmt::DependentScopeDeclRefExprClass:
1785 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1786 }
1787 }
1788};
1789class MemberRefVisit : public VisitorJob {
1790public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001791 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001792 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1793 L.getPtrEncoding()) {}
1794 static bool classof(const VisitorJob *VJ) {
1795 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1796 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001797 const FieldDecl *get() const {
1798 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001799 }
1800 SourceLocation getLoc() const {
1801 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1802 }
1803};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001804class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001805 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001806 VisitorWorkList &WL;
1807 CXCursor Parent;
1808public:
1809 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1810 : WL(wl), Parent(parent) {}
1811
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001812 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1813 void VisitBlockExpr(const BlockExpr *B);
1814 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1815 void VisitCompoundStmt(const CompoundStmt *S);
1816 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1817 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1818 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1819 void VisitCXXNewExpr(const CXXNewExpr *E);
1820 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1821 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1822 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1823 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1824 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1825 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1826 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1827 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1828 void VisitDeclRefExpr(const DeclRefExpr *D);
1829 void VisitDeclStmt(const DeclStmt *S);
1830 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1831 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1832 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1833 void VisitForStmt(const ForStmt *FS);
1834 void VisitGotoStmt(const GotoStmt *GS);
1835 void VisitIfStmt(const IfStmt *If);
1836 void VisitInitListExpr(const InitListExpr *IE);
1837 void VisitMemberExpr(const MemberExpr *M);
1838 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1839 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1840 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1841 void VisitOverloadExpr(const OverloadExpr *E);
1842 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1843 void VisitStmt(const Stmt *S);
1844 void VisitSwitchStmt(const SwitchStmt *S);
1845 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001846 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1847 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1848 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1849 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1850 void VisitVAArgExpr(const VAArgExpr *E);
1851 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1852 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1853 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1854 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001855 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1856 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001857 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001858
Guy Benyei11169dd2012-12-18 14:30:41 +00001859private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001860 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001861 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1862 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001863 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1864 void AddStmt(const Stmt *S);
1865 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001866 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001867 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001868 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001869};
1870} // end anonyous namespace
1871
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001872void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001873 // 'S' should always be non-null, since it comes from the
1874 // statement we are visiting.
1875 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1876}
1877
1878void
1879EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1880 if (Qualifier)
1881 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1882}
1883
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001884void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001885 if (S)
1886 WL.push_back(StmtVisit(S, Parent));
1887}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001888void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001889 if (D)
1890 WL.push_back(DeclVisit(D, Parent, isFirst));
1891}
1892void EnqueueVisitor::
1893 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1894 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001895 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001896}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001897void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001898 if (D)
1899 WL.push_back(MemberRefVisit(D, L, Parent));
1900}
1901void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1902 if (TI)
1903 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1904 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001905void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001906 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001907 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001908 AddStmt(*Child);
1909 }
1910 if (size == WL.size())
1911 return;
1912 // Now reverse the entries we just added. This will match the DFS
1913 // ordering performed by the worklist.
1914 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1915 std::reverse(I, E);
1916}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001917namespace {
1918class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1919 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001920 /// \brief Process clauses with list of variables.
1921 template <typename T>
1922 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001923public:
1924 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1925#define OPENMP_CLAUSE(Name, Class) \
1926 void Visit##Class(const Class *C);
1927#include "clang/Basic/OpenMPKinds.def"
1928};
1929
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001930void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1931 Visitor->AddStmt(C->getCondition());
1932}
1933
Alexey Bataev568a8332014-03-06 06:15:19 +00001934void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1935 Visitor->AddStmt(C->getNumThreads());
1936}
1937
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001938void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001939
1940template<typename T>
1941void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
1942 for (typename T::varlist_const_iterator I = Node->varlist_begin(),
1943 E = Node->varlist_end();
1944 I != E; ++I)
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001945 Visitor->AddStmt(*I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001946}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001947
1948void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001949 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001950}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001951void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1952 const OMPFirstprivateClause *C) {
1953 VisitOMPClauseList(C);
1954}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001955void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001956 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001957}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001958}
Alexey Bataev756c1962013-09-24 03:17:45 +00001959
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001960void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1961 unsigned size = WL.size();
1962 OMPClauseEnqueue Visitor(this);
1963 Visitor.Visit(S);
1964 if (size == WL.size())
1965 return;
1966 // Now reverse the entries we just added. This will match the DFS
1967 // ordering performed by the worklist.
1968 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1969 std::reverse(I, E);
1970}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001971void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001972 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1973}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001974void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001975 AddDecl(B->getBlockDecl());
1976}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001977void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001978 EnqueueChildren(E);
1979 AddTypeLoc(E->getTypeSourceInfo());
1980}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001981void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1982 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001983 E = S->body_rend(); I != E; ++I) {
1984 AddStmt(*I);
1985 }
1986}
1987void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001988VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001989 AddStmt(S->getSubStmt());
1990 AddDeclarationNameInfo(S);
1991 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1992 AddNestedNameSpecifierLoc(QualifierLoc);
1993}
1994
1995void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001996VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001997 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1998 AddDeclarationNameInfo(E);
1999 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2000 AddNestedNameSpecifierLoc(QualifierLoc);
2001 if (!E->isImplicitAccess())
2002 AddStmt(E->getBase());
2003}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002004void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002005 // Enqueue the initializer , if any.
2006 AddStmt(E->getInitializer());
2007 // Enqueue the array size, if any.
2008 AddStmt(E->getArraySize());
2009 // Enqueue the allocated type.
2010 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2011 // Enqueue the placement arguments.
2012 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2013 AddStmt(E->getPlacementArg(I-1));
2014}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002015void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002016 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2017 AddStmt(CE->getArg(I-1));
2018 AddStmt(CE->getCallee());
2019 AddStmt(CE->getArg(0));
2020}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002021void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2022 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002023 // Visit the name of the type being destroyed.
2024 AddTypeLoc(E->getDestroyedTypeInfo());
2025 // Visit the scope type that looks disturbingly like the nested-name-specifier
2026 // but isn't.
2027 AddTypeLoc(E->getScopeTypeInfo());
2028 // Visit the nested-name-specifier.
2029 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2030 AddNestedNameSpecifierLoc(QualifierLoc);
2031 // Visit base expression.
2032 AddStmt(E->getBase());
2033}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002034void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2035 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002036 AddTypeLoc(E->getTypeSourceInfo());
2037}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002038void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2039 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002040 EnqueueChildren(E);
2041 AddTypeLoc(E->getTypeSourceInfo());
2042}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002043void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002044 EnqueueChildren(E);
2045 if (E->isTypeOperand())
2046 AddTypeLoc(E->getTypeOperandSourceInfo());
2047}
2048
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002049void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2050 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002051 EnqueueChildren(E);
2052 AddTypeLoc(E->getTypeSourceInfo());
2053}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002054void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002055 EnqueueChildren(E);
2056 if (E->isTypeOperand())
2057 AddTypeLoc(E->getTypeOperandSourceInfo());
2058}
2059
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002060void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002061 EnqueueChildren(S);
2062 AddDecl(S->getExceptionDecl());
2063}
2064
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002065void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002066 if (DR->hasExplicitTemplateArgs()) {
2067 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2068 }
2069 WL.push_back(DeclRefExprParts(DR, Parent));
2070}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002071void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2072 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002073 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2074 AddDeclarationNameInfo(E);
2075 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2076}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002077void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002078 unsigned size = WL.size();
2079 bool isFirst = true;
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002080 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00002081 D != DEnd; ++D) {
2082 AddDecl(*D, isFirst);
2083 isFirst = false;
2084 }
2085 if (size == WL.size())
2086 return;
2087 // Now reverse the entries we just added. This will match the DFS
2088 // ordering performed by the worklist.
2089 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2090 std::reverse(I, E);
2091}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002092void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002093 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002094 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002095 D = E->designators_rbegin(), DEnd = E->designators_rend();
2096 D != DEnd; ++D) {
2097 if (D->isFieldDesignator()) {
2098 if (FieldDecl *Field = D->getField())
2099 AddMemberRef(Field, D->getFieldLoc());
2100 continue;
2101 }
2102 if (D->isArrayDesignator()) {
2103 AddStmt(E->getArrayIndex(*D));
2104 continue;
2105 }
2106 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2107 AddStmt(E->getArrayRangeEnd(*D));
2108 AddStmt(E->getArrayRangeStart(*D));
2109 }
2110}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002111void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002112 EnqueueChildren(E);
2113 AddTypeLoc(E->getTypeInfoAsWritten());
2114}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002115void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002116 AddStmt(FS->getBody());
2117 AddStmt(FS->getInc());
2118 AddStmt(FS->getCond());
2119 AddDecl(FS->getConditionVariable());
2120 AddStmt(FS->getInit());
2121}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002122void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002123 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2124}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002125void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002126 AddStmt(If->getElse());
2127 AddStmt(If->getThen());
2128 AddStmt(If->getCond());
2129 AddDecl(If->getConditionVariable());
2130}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002131void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002132 // We care about the syntactic form of the initializer list, only.
2133 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2134 IE = Syntactic;
2135 EnqueueChildren(IE);
2136}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002137void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002138 WL.push_back(MemberExprParts(M, Parent));
2139
2140 // If the base of the member access expression is an implicit 'this', don't
2141 // visit it.
2142 // FIXME: If we ever want to show these implicit accesses, this will be
2143 // unfortunate. However, clang_getCursor() relies on this behavior.
2144 if (!M->isImplicitAccess())
2145 AddStmt(M->getBase());
2146}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002147void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002148 AddTypeLoc(E->getEncodedTypeSourceInfo());
2149}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002150void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002151 EnqueueChildren(M);
2152 AddTypeLoc(M->getClassReceiverTypeInfo());
2153}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002154void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002155 // Visit the components of the offsetof expression.
2156 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2157 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2158 const OffsetOfNode &Node = E->getComponent(I-1);
2159 switch (Node.getKind()) {
2160 case OffsetOfNode::Array:
2161 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2162 break;
2163 case OffsetOfNode::Field:
2164 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2165 break;
2166 case OffsetOfNode::Identifier:
2167 case OffsetOfNode::Base:
2168 continue;
2169 }
2170 }
2171 // Visit the type into which we're computing the offset.
2172 AddTypeLoc(E->getTypeSourceInfo());
2173}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002174void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002175 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2176 WL.push_back(OverloadExprParts(E, Parent));
2177}
2178void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002179 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002180 EnqueueChildren(E);
2181 if (E->isArgumentType())
2182 AddTypeLoc(E->getArgumentTypeInfo());
2183}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002184void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002185 EnqueueChildren(S);
2186}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002187void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002188 AddStmt(S->getBody());
2189 AddStmt(S->getCond());
2190 AddDecl(S->getConditionVariable());
2191}
2192
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002193void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002194 AddStmt(W->getBody());
2195 AddStmt(W->getCond());
2196 AddDecl(W->getConditionVariable());
2197}
2198
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002199void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002200 for (unsigned I = E->getNumArgs(); I > 0; --I)
2201 AddTypeLoc(E->getArg(I-1));
2202}
2203
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002204void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002205 AddTypeLoc(E->getQueriedTypeSourceInfo());
2206}
2207
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002208void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002209 EnqueueChildren(E);
2210}
2211
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002212void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002213 VisitOverloadExpr(U);
2214 if (!U->isImplicitAccess())
2215 AddStmt(U->getBase());
2216}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002218 AddStmt(E->getSubExpr());
2219 AddTypeLoc(E->getWrittenTypeInfo());
2220}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002221void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002222 WL.push_back(SizeOfPackExprParts(E, Parent));
2223}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002224void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002225 // If the opaque value has a source expression, just transparently
2226 // visit that. This is useful for (e.g.) pseudo-object expressions.
2227 if (Expr *SourceExpr = E->getSourceExpr())
2228 return Visit(SourceExpr);
2229}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002230void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002231 AddStmt(E->getBody());
2232 WL.push_back(LambdaExprParts(E, Parent));
2233}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002234void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002235 // Treat the expression like its syntactic form.
2236 Visit(E->getSyntacticForm());
2237}
2238
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002239void EnqueueVisitor::VisitOMPExecutableDirective(
2240 const OMPExecutableDirective *D) {
2241 EnqueueChildren(D);
2242 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2243 E = D->clauses().end();
2244 I != E; ++I)
2245 EnqueueChildren(*I);
2246}
2247
2248void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2249 VisitOMPExecutableDirective(D);
2250}
2251
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002252void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2253 VisitOMPExecutableDirective(D);
2254}
2255
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002256void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002257 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2258}
2259
2260bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2261 if (RegionOfInterest.isValid()) {
2262 SourceRange Range = getRawCursorExtent(C);
2263 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2264 return false;
2265 }
2266 return true;
2267}
2268
2269bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2270 while (!WL.empty()) {
2271 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002272 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002273
2274 // Set the Parent field, then back to its old value once we're done.
2275 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2276
2277 switch (LI.getKind()) {
2278 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002279 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002280 if (!D)
2281 continue;
2282
2283 // For now, perform default visitation for Decls.
2284 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2285 cast<DeclVisit>(&LI)->isFirst())))
2286 return true;
2287
2288 continue;
2289 }
2290 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2291 const ASTTemplateArgumentListInfo *ArgList =
2292 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2293 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2294 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2295 Arg != ArgEnd; ++Arg) {
2296 if (VisitTemplateArgumentLoc(*Arg))
2297 return true;
2298 }
2299 continue;
2300 }
2301 case VisitorJob::TypeLocVisitKind: {
2302 // Perform default visitation for TypeLocs.
2303 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2304 return true;
2305 continue;
2306 }
2307 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002308 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002309 if (LabelStmt *stmt = LS->getStmt()) {
2310 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2311 TU))) {
2312 return true;
2313 }
2314 }
2315 continue;
2316 }
2317
2318 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2319 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2320 if (VisitNestedNameSpecifierLoc(V->get()))
2321 return true;
2322 continue;
2323 }
2324
2325 case VisitorJob::DeclarationNameInfoVisitKind: {
2326 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2327 ->get()))
2328 return true;
2329 continue;
2330 }
2331 case VisitorJob::MemberRefVisitKind: {
2332 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2333 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2334 return true;
2335 continue;
2336 }
2337 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002338 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002339 if (!S)
2340 continue;
2341
2342 // Update the current cursor.
2343 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2344 if (!IsInRegionOfInterest(Cursor))
2345 continue;
2346 switch (Visitor(Cursor, Parent, ClientData)) {
2347 case CXChildVisit_Break: return true;
2348 case CXChildVisit_Continue: break;
2349 case CXChildVisit_Recurse:
2350 if (PostChildrenVisitor)
2351 WL.push_back(PostChildrenVisit(0, Cursor));
2352 EnqueueWorkList(WL, S);
2353 break;
2354 }
2355 continue;
2356 }
2357 case VisitorJob::MemberExprPartsKind: {
2358 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002359 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002360
2361 // Visit the nested-name-specifier
2362 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2363 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2364 return true;
2365
2366 // Visit the declaration name.
2367 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2368 return true;
2369
2370 // Visit the explicitly-specified template arguments, if any.
2371 if (M->hasExplicitTemplateArgs()) {
2372 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2373 *ArgEnd = Arg + M->getNumTemplateArgs();
2374 Arg != ArgEnd; ++Arg) {
2375 if (VisitTemplateArgumentLoc(*Arg))
2376 return true;
2377 }
2378 }
2379 continue;
2380 }
2381 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002382 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002383 // Visit nested-name-specifier, if present.
2384 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2385 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2386 return true;
2387 // Visit declaration name.
2388 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2389 return true;
2390 continue;
2391 }
2392 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002393 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002394 // Visit the nested-name-specifier.
2395 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2396 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2397 return true;
2398 // Visit the declaration name.
2399 if (VisitDeclarationNameInfo(O->getNameInfo()))
2400 return true;
2401 // Visit the overloaded declaration reference.
2402 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2403 return true;
2404 continue;
2405 }
2406 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002407 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002408 NamedDecl *Pack = E->getPack();
2409 if (isa<TemplateTypeParmDecl>(Pack)) {
2410 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2411 E->getPackLoc(), TU)))
2412 return true;
2413
2414 continue;
2415 }
2416
2417 if (isa<TemplateTemplateParmDecl>(Pack)) {
2418 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2419 E->getPackLoc(), TU)))
2420 return true;
2421
2422 continue;
2423 }
2424
2425 // Non-type template parameter packs and function parameter packs are
2426 // treated like DeclRefExpr cursors.
2427 continue;
2428 }
2429
2430 case VisitorJob::LambdaExprPartsKind: {
2431 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002432 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002433 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2434 CEnd = E->explicit_capture_end();
2435 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002436 // FIXME: Lambda init-captures.
2437 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002438 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002439
Guy Benyei11169dd2012-12-18 14:30:41 +00002440 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2441 C->getLocation(),
2442 TU)))
2443 return true;
2444 }
2445
2446 // Visit parameters and return type, if present.
2447 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2448 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2449 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2450 // Visit the whole type.
2451 if (Visit(TL))
2452 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002453 } else if (FunctionProtoTypeLoc Proto =
2454 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002455 if (E->hasExplicitParameters()) {
2456 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002457 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2458 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002459 return true;
2460 } else {
2461 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002462 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002463 return true;
2464 }
2465 }
2466 }
2467 break;
2468 }
2469
2470 case VisitorJob::PostChildrenVisitKind:
2471 if (PostChildrenVisitor(Parent, ClientData))
2472 return true;
2473 break;
2474 }
2475 }
2476 return false;
2477}
2478
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002479bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002480 VisitorWorkList *WL = 0;
2481 if (!WorkListFreeList.empty()) {
2482 WL = WorkListFreeList.back();
2483 WL->clear();
2484 WorkListFreeList.pop_back();
2485 }
2486 else {
2487 WL = new VisitorWorkList();
2488 WorkListCache.push_back(WL);
2489 }
2490 EnqueueWorkList(*WL, S);
2491 bool result = RunVisitorWorkList(*WL);
2492 WorkListFreeList.push_back(WL);
2493 return result;
2494}
2495
2496namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002497typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002498RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2499 const DeclarationNameInfo &NI,
2500 const SourceRange &QLoc,
2501 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2502 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2503 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2504 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2505
2506 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2507
2508 RefNamePieces Pieces;
2509
2510 if (WantQualifier && QLoc.isValid())
2511 Pieces.push_back(QLoc);
2512
2513 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2514 Pieces.push_back(NI.getLoc());
2515
2516 if (WantTemplateArgs && TemplateArgs)
2517 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2518 TemplateArgs->RAngleLoc));
2519
2520 if (Kind == DeclarationName::CXXOperatorName) {
2521 Pieces.push_back(SourceLocation::getFromRawEncoding(
2522 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2523 Pieces.push_back(SourceLocation::getFromRawEncoding(
2524 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2525 }
2526
2527 if (WantSinglePiece) {
2528 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2529 Pieces.clear();
2530 Pieces.push_back(R);
2531 }
2532
2533 return Pieces;
2534}
2535}
2536
2537//===----------------------------------------------------------------------===//
2538// Misc. API hooks.
2539//===----------------------------------------------------------------------===//
2540
2541static llvm::sys::Mutex EnableMultithreadingMutex;
2542static bool EnabledMultithreading;
2543
Chad Rosier05c71aa2013-03-27 18:28:23 +00002544static void fatal_error_handler(void *user_data, const std::string& reason,
2545 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002546 // Write the result out to stderr avoiding errs() because raw_ostreams can
2547 // call report_fatal_error.
2548 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2549 ::abort();
2550}
2551
2552extern "C" {
2553CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2554 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002555 // We use crash recovery to make some of our APIs more reliable, implicitly
2556 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002557 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2558 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002559
2560 // Enable support for multithreading in LLVM.
2561 {
2562 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2563 if (!EnabledMultithreading) {
2564 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2565 llvm::llvm_start_multithreaded();
2566 EnabledMultithreading = true;
2567 }
2568 }
2569
2570 CIndexer *CIdxr = new CIndexer();
2571 if (excludeDeclarationsFromPCH)
2572 CIdxr->setOnlyLocalDecls();
2573 if (displayDiagnostics)
2574 CIdxr->setDisplayDiagnostics();
2575
2576 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2577 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2578 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2579 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2580 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2581 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2582
2583 return CIdxr;
2584}
2585
2586void clang_disposeIndex(CXIndex CIdx) {
2587 if (CIdx)
2588 delete static_cast<CIndexer *>(CIdx);
2589}
2590
2591void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2592 if (CIdx)
2593 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2594}
2595
2596unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2597 if (CIdx)
2598 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2599 return 0;
2600}
2601
2602void clang_toggleCrashRecovery(unsigned isEnabled) {
2603 if (isEnabled)
2604 llvm::CrashRecoveryContext::Enable();
2605 else
2606 llvm::CrashRecoveryContext::Disable();
2607}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002608
Guy Benyei11169dd2012-12-18 14:30:41 +00002609CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2610 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002611 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002612 enum CXErrorCode Result =
2613 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002614 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002615 assert((TU && Result == CXError_Success) ||
2616 (!TU && Result != CXError_Success));
2617 return TU;
2618}
2619
2620enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2621 const char *ast_filename,
2622 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002623 if (out_TU)
2624 *out_TU = NULL;
2625
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002626 if (!CIdx || !ast_filename || !out_TU)
2627 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002628
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002629 LOG_FUNC_SECTION {
2630 *Log << ast_filename;
2631 }
2632
Guy Benyei11169dd2012-12-18 14:30:41 +00002633 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2634 FileSystemOptions FileSystemOpts;
2635
2636 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002637 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002638 CXXIdx->getOnlyLocalDecls(), None,
2639 /*CaptureDiagnostics=*/true,
2640 /*AllowPCHWithCompilerErrors=*/true,
2641 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002642 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2643 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002644}
2645
2646unsigned clang_defaultEditingTranslationUnitOptions() {
2647 return CXTranslationUnit_PrecompiledPreamble |
2648 CXTranslationUnit_CacheCompletionResults;
2649}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002650
Guy Benyei11169dd2012-12-18 14:30:41 +00002651CXTranslationUnit
2652clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2653 const char *source_filename,
2654 int num_command_line_args,
2655 const char * const *command_line_args,
2656 unsigned num_unsaved_files,
2657 struct CXUnsavedFile *unsaved_files) {
2658 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2659 return clang_parseTranslationUnit(CIdx, source_filename,
2660 command_line_args, num_command_line_args,
2661 unsaved_files, num_unsaved_files,
2662 Options);
2663}
2664
2665struct ParseTranslationUnitInfo {
2666 CXIndex CIdx;
2667 const char *source_filename;
2668 const char *const *command_line_args;
2669 int num_command_line_args;
2670 struct CXUnsavedFile *unsaved_files;
2671 unsigned num_unsaved_files;
2672 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002673 CXTranslationUnit *out_TU;
2674 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002675};
2676static void clang_parseTranslationUnit_Impl(void *UserData) {
2677 ParseTranslationUnitInfo *PTUI =
2678 static_cast<ParseTranslationUnitInfo*>(UserData);
2679 CXIndex CIdx = PTUI->CIdx;
2680 const char *source_filename = PTUI->source_filename;
2681 const char * const *command_line_args = PTUI->command_line_args;
2682 int num_command_line_args = PTUI->num_command_line_args;
2683 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2684 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2685 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002686 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002687
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002688 // Set up the initial return values.
2689 if (out_TU)
2690 *out_TU = NULL;
2691 PTUI->result = CXError_Failure;
2692
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002693 // Check arguments.
2694 if (!CIdx || !out_TU ||
2695 (unsaved_files == NULL && num_unsaved_files != 0)) {
2696 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002697 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002698 }
2699
Guy Benyei11169dd2012-12-18 14:30:41 +00002700 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2701
2702 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2703 setThreadBackgroundPriority();
2704
2705 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2706 // FIXME: Add a flag for modules.
2707 TranslationUnitKind TUKind
2708 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002709 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002710 = options & CXTranslationUnit_CacheCompletionResults;
2711 bool IncludeBriefCommentsInCodeCompletion
2712 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2713 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2714 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2715
2716 // Configure the diagnostics.
2717 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002718 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002719
2720 // Recover resources if we crash before exiting this function.
2721 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2722 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2723 DiagCleanup(Diags.getPtr());
2724
Ahmed Charlesb8984322014-03-07 20:03:18 +00002725 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2726 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002727
2728 // Recover resources if we crash before exiting this function.
2729 llvm::CrashRecoveryContextCleanupRegistrar<
2730 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2731
2732 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2733 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2734 const llvm::MemoryBuffer *Buffer
2735 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2736 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2737 Buffer));
2738 }
2739
Ahmed Charlesb8984322014-03-07 20:03:18 +00002740 std::unique_ptr<std::vector<const char *>> Args(
2741 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002742
2743 // Recover resources if we crash before exiting this method.
2744 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2745 ArgsCleanup(Args.get());
2746
2747 // Since the Clang C library is primarily used by batch tools dealing with
2748 // (often very broken) source code, where spell-checking can have a
2749 // significant negative impact on performance (particularly when
2750 // precompiled headers are involved), we disable it by default.
2751 // Only do this if we haven't found a spell-checking-related argument.
2752 bool FoundSpellCheckingArgument = false;
2753 for (int I = 0; I != num_command_line_args; ++I) {
2754 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2755 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2756 FoundSpellCheckingArgument = true;
2757 break;
2758 }
2759 }
2760 if (!FoundSpellCheckingArgument)
2761 Args->push_back("-fno-spell-checking");
2762
2763 Args->insert(Args->end(), command_line_args,
2764 command_line_args + num_command_line_args);
2765
2766 // The 'source_filename' argument is optional. If the caller does not
2767 // specify it then it is assumed that the source file is specified
2768 // in the actual argument list.
2769 // Put the source file after command_line_args otherwise if '-x' flag is
2770 // present it will be unused.
2771 if (source_filename)
2772 Args->push_back(source_filename);
2773
2774 // Do we need the detailed preprocessing record?
2775 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2776 Args->push_back("-Xclang");
2777 Args->push_back("-detailed-preprocessing-record");
2778 }
2779
2780 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002781 std::unique_ptr<ASTUnit> ErrUnit;
2782 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
2783 Args->size() ? &(*Args)[0] : 0
2784 /* vector::data() not portable */,
2785 Args->size() ? (&(*Args)[0] + Args->size()) : 0, Diags,
2786 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2787 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2788 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2789 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2790 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2791 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002792
2793 if (NumErrors != Diags->getClient()->getNumErrors()) {
2794 // Make sure to check that 'Unit' is non-NULL.
2795 if (CXXIdx->getDisplayDiagnostics())
2796 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2797 }
2798
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002799 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2800 PTUI->result = CXError_ASTReadError;
2801 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002802 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002803 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2804 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002805}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002806
2807CXTranslationUnit
2808clang_parseTranslationUnit(CXIndex CIdx,
2809 const char *source_filename,
2810 const char *const *command_line_args,
2811 int num_command_line_args,
2812 struct CXUnsavedFile *unsaved_files,
2813 unsigned num_unsaved_files,
2814 unsigned options) {
2815 CXTranslationUnit TU;
2816 enum CXErrorCode Result = clang_parseTranslationUnit2(
2817 CIdx, source_filename, command_line_args, num_command_line_args,
2818 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002819 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002820 assert((TU && Result == CXError_Success) ||
2821 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002822 return TU;
2823}
2824
2825enum CXErrorCode clang_parseTranslationUnit2(
2826 CXIndex CIdx,
2827 const char *source_filename,
2828 const char *const *command_line_args,
2829 int num_command_line_args,
2830 struct CXUnsavedFile *unsaved_files,
2831 unsigned num_unsaved_files,
2832 unsigned options,
2833 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002834 LOG_FUNC_SECTION {
2835 *Log << source_filename << ": ";
2836 for (int i = 0; i != num_command_line_args; ++i)
2837 *Log << command_line_args[i] << " ";
2838 }
2839
Guy Benyei11169dd2012-12-18 14:30:41 +00002840 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2841 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002842 num_unsaved_files, options, out_TU,
2843 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002844 llvm::CrashRecoveryContext CRC;
2845
2846 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2847 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2848 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2849 fprintf(stderr, " 'command_line_args' : [");
2850 for (int i = 0; i != num_command_line_args; ++i) {
2851 if (i)
2852 fprintf(stderr, ", ");
2853 fprintf(stderr, "'%s'", command_line_args[i]);
2854 }
2855 fprintf(stderr, "],\n");
2856 fprintf(stderr, " 'unsaved_files' : [");
2857 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2858 if (i)
2859 fprintf(stderr, ", ");
2860 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2861 unsaved_files[i].Length);
2862 }
2863 fprintf(stderr, "],\n");
2864 fprintf(stderr, " 'options' : %d,\n", options);
2865 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002866
2867 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002868 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002869 if (CXTranslationUnit *TU = PTUI.out_TU)
2870 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002871 }
2872
2873 return PTUI.result;
2874}
2875
2876unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2877 return CXSaveTranslationUnit_None;
2878}
2879
2880namespace {
2881
2882struct SaveTranslationUnitInfo {
2883 CXTranslationUnit TU;
2884 const char *FileName;
2885 unsigned options;
2886 CXSaveError result;
2887};
2888
2889}
2890
2891static void clang_saveTranslationUnit_Impl(void *UserData) {
2892 SaveTranslationUnitInfo *STUI =
2893 static_cast<SaveTranslationUnitInfo*>(UserData);
2894
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002895 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002896 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2897 setThreadBackgroundPriority();
2898
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002899 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002900 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2901}
2902
2903int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2904 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002905 LOG_FUNC_SECTION {
2906 *Log << TU << ' ' << FileName;
2907 }
2908
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002909 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002910 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002911 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002912 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002913
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002914 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002915 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2916 if (!CXXUnit->hasSema())
2917 return CXSaveError_InvalidTU;
2918
2919 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2920
2921 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2922 getenv("LIBCLANG_NOTHREADS")) {
2923 clang_saveTranslationUnit_Impl(&STUI);
2924
2925 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2926 PrintLibclangResourceUsage(TU);
2927
2928 return STUI.result;
2929 }
2930
2931 // We have an AST that has invalid nodes due to compiler errors.
2932 // Use a crash recovery thread for protection.
2933
2934 llvm::CrashRecoveryContext CRC;
2935
2936 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2937 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2938 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2939 fprintf(stderr, " 'options' : %d,\n", options);
2940 fprintf(stderr, "}\n");
2941
2942 return CXSaveError_Unknown;
2943
2944 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2945 PrintLibclangResourceUsage(TU);
2946 }
2947
2948 return STUI.result;
2949}
2950
2951void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2952 if (CTUnit) {
2953 // If the translation unit has been marked as unsafe to free, just discard
2954 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002955 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2956 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002957 return;
2958
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002959 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002960 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002961 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2962 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002963 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002964 delete CTUnit;
2965 }
2966}
2967
2968unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2969 return CXReparse_None;
2970}
2971
2972struct ReparseTranslationUnitInfo {
2973 CXTranslationUnit TU;
2974 unsigned num_unsaved_files;
2975 struct CXUnsavedFile *unsaved_files;
2976 unsigned options;
2977 int result;
2978};
2979
2980static void clang_reparseTranslationUnit_Impl(void *UserData) {
2981 ReparseTranslationUnitInfo *RTUI =
2982 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002983 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002984
Guy Benyei11169dd2012-12-18 14:30:41 +00002985 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002986 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2987 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2988 unsigned options = RTUI->options;
2989 (void) options;
2990
2991 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002992 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002993 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002994 RTUI->result = CXError_InvalidArguments;
2995 return;
2996 }
2997 if (unsaved_files == NULL && num_unsaved_files != 0) {
2998 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00002999 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003000 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003001
3002 // Reset the associated diagnostics.
3003 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3004 TU->Diagnostics = 0;
3005
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003006 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003007 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3008 setThreadBackgroundPriority();
3009
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003010 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003011 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003012
3013 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3014 new std::vector<ASTUnit::RemappedFile>());
3015
Guy Benyei11169dd2012-12-18 14:30:41 +00003016 // Recover resources if we crash before exiting this function.
3017 llvm::CrashRecoveryContextCleanupRegistrar<
3018 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3019
3020 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3021 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3022 const llvm::MemoryBuffer *Buffer
3023 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3024 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3025 Buffer));
3026 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003027
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003028 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003029 RTUI->result = CXError_Success;
3030 else if (isASTReadError(CXXUnit))
3031 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003032}
3033
3034int clang_reparseTranslationUnit(CXTranslationUnit TU,
3035 unsigned num_unsaved_files,
3036 struct CXUnsavedFile *unsaved_files,
3037 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003038 LOG_FUNC_SECTION {
3039 *Log << TU;
3040 }
3041
Guy Benyei11169dd2012-12-18 14:30:41 +00003042 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003043 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003044
3045 if (getenv("LIBCLANG_NOTHREADS")) {
3046 clang_reparseTranslationUnit_Impl(&RTUI);
3047 return RTUI.result;
3048 }
3049
3050 llvm::CrashRecoveryContext CRC;
3051
3052 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3053 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003054 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003055 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003056 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3057 PrintLibclangResourceUsage(TU);
3058
3059 return RTUI.result;
3060}
3061
3062
3063CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003064 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003065 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003066 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003067 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003068
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003069 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003070 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003071}
3072
3073CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003074 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003075 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003076 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003077 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003078
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003079 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003080 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3081}
3082
3083} // end: extern "C"
3084
3085//===----------------------------------------------------------------------===//
3086// CXFile Operations.
3087//===----------------------------------------------------------------------===//
3088
3089extern "C" {
3090CXString clang_getFileName(CXFile SFile) {
3091 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003092 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003093
3094 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003095 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003096}
3097
3098time_t clang_getFileTime(CXFile SFile) {
3099 if (!SFile)
3100 return 0;
3101
3102 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3103 return FEnt->getModificationTime();
3104}
3105
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003106CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003107 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003108 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003109 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003110 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003111
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003112 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003113
3114 FileManager &FMgr = CXXUnit->getFileManager();
3115 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3116}
3117
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003118unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3119 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003120 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003121 LOG_BAD_TU(TU);
3122 return 0;
3123 }
3124
3125 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003126 return 0;
3127
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003128 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003129 FileEntry *FEnt = static_cast<FileEntry *>(file);
3130 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3131 .isFileMultipleIncludeGuarded(FEnt);
3132}
3133
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003134int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3135 if (!file || !outID)
3136 return 1;
3137
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003138 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003139 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3140 outID->data[0] = ID.getDevice();
3141 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003142 outID->data[2] = FEnt->getModificationTime();
3143 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003144}
3145
Guy Benyei11169dd2012-12-18 14:30:41 +00003146} // end: extern "C"
3147
3148//===----------------------------------------------------------------------===//
3149// CXCursor Operations.
3150//===----------------------------------------------------------------------===//
3151
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003152static const Decl *getDeclFromExpr(const Stmt *E) {
3153 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003154 return getDeclFromExpr(CE->getSubExpr());
3155
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003156 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003157 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003158 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003159 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003160 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003161 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003162 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003163 if (PRE->isExplicitProperty())
3164 return PRE->getExplicitProperty();
3165 // It could be messaging both getter and setter as in:
3166 // ++myobj.myprop;
3167 // in which case prefer to associate the setter since it is less obvious
3168 // from inspecting the source that the setter is going to get called.
3169 if (PRE->isMessagingSetter())
3170 return PRE->getImplicitPropertySetter();
3171 return PRE->getImplicitPropertyGetter();
3172 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003173 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003174 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003175 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003176 if (Expr *Src = OVE->getSourceExpr())
3177 return getDeclFromExpr(Src);
3178
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003179 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003180 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003181 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003182 if (!CE->isElidable())
3183 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003184 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003185 return OME->getMethodDecl();
3186
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003187 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003188 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003189 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003190 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3191 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003192 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003193 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3194 isa<ParmVarDecl>(SizeOfPack->getPack()))
3195 return SizeOfPack->getPack();
3196
3197 return 0;
3198}
3199
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003200static SourceLocation getLocationFromExpr(const Expr *E) {
3201 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003202 return getLocationFromExpr(CE->getSubExpr());
3203
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003204 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003205 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003206 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003207 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003208 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003209 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003210 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003211 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003212 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003213 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003214 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003215 return PropRef->getLocation();
3216
3217 return E->getLocStart();
3218}
3219
3220extern "C" {
3221
3222unsigned clang_visitChildren(CXCursor parent,
3223 CXCursorVisitor visitor,
3224 CXClientData client_data) {
3225 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3226 /*VisitPreprocessorLast=*/false);
3227 return CursorVis.VisitChildren(parent);
3228}
3229
3230#ifndef __has_feature
3231#define __has_feature(x) 0
3232#endif
3233#if __has_feature(blocks)
3234typedef enum CXChildVisitResult
3235 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3236
3237static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3238 CXClientData client_data) {
3239 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3240 return block(cursor, parent);
3241}
3242#else
3243// If we are compiled with a compiler that doesn't have native blocks support,
3244// define and call the block manually, so the
3245typedef struct _CXChildVisitResult
3246{
3247 void *isa;
3248 int flags;
3249 int reserved;
3250 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3251 CXCursor);
3252} *CXCursorVisitorBlock;
3253
3254static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3255 CXClientData client_data) {
3256 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3257 return block->invoke(block, cursor, parent);
3258}
3259#endif
3260
3261
3262unsigned clang_visitChildrenWithBlock(CXCursor parent,
3263 CXCursorVisitorBlock block) {
3264 return clang_visitChildren(parent, visitWithBlock, block);
3265}
3266
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003267static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003268 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003269 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003270
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003271 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003272 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003273 if (const ObjCPropertyImplDecl *PropImpl =
3274 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003275 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003276 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003277
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003278 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003279 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003280 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003281
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003282 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003283 }
3284
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003285 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003286 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003287
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003288 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003289 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3290 // and returns different names. NamedDecl returns the class name and
3291 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003292 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003293
3294 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003295 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003296
3297 SmallString<1024> S;
3298 llvm::raw_svector_ostream os(S);
3299 ND->printName(os);
3300
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003301 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003302}
3303
3304CXString clang_getCursorSpelling(CXCursor C) {
3305 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003306 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003307
3308 if (clang_isReference(C.kind)) {
3309 switch (C.kind) {
3310 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003311 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003312 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003313 }
3314 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003315 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003316 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003317 }
3318 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003319 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003320 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003321 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003322 }
3323 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003324 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003325 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003326 }
3327 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003328 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003329 assert(Type && "Missing type decl");
3330
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003331 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003332 getAsString());
3333 }
3334 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003335 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003336 assert(Template && "Missing template decl");
3337
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003338 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003339 }
3340
3341 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003342 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003343 assert(NS && "Missing namespace decl");
3344
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003345 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003346 }
3347
3348 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003349 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003350 assert(Field && "Missing member decl");
3351
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003352 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003353 }
3354
3355 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003356 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003357 assert(Label && "Missing label");
3358
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003359 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003360 }
3361
3362 case CXCursor_OverloadedDeclRef: {
3363 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003364 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3365 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003366 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003367 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003368 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003369 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003370 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003371 OverloadedTemplateStorage *Ovl
3372 = Storage.get<OverloadedTemplateStorage*>();
3373 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003374 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003375 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003376 }
3377
3378 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003379 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 assert(Var && "Missing variable decl");
3381
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003382 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003383 }
3384
3385 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003386 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003387 }
3388 }
3389
3390 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003391 const Expr *E = getCursorExpr(C);
3392
3393 if (C.kind == CXCursor_ObjCStringLiteral ||
3394 C.kind == CXCursor_StringLiteral) {
3395 const StringLiteral *SLit;
3396 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3397 SLit = OSL->getString();
3398 } else {
3399 SLit = cast<StringLiteral>(E);
3400 }
3401 SmallString<256> Buf;
3402 llvm::raw_svector_ostream OS(Buf);
3403 SLit->outputString(OS);
3404 return cxstring::createDup(OS.str());
3405 }
3406
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003407 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003408 if (D)
3409 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003410 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003411 }
3412
3413 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003414 const Stmt *S = getCursorStmt(C);
3415 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003416 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003417
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003418 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003419 }
3420
3421 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003422 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003423 ->getNameStart());
3424
3425 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003426 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003427 ->getNameStart());
3428
3429 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003430 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003431
3432 if (clang_isDeclaration(C.kind))
3433 return getDeclSpelling(getCursorDecl(C));
3434
3435 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003436 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003437 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003438 }
3439
3440 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003441 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003442 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003443 }
3444
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003445 if (C.kind == CXCursor_PackedAttr) {
3446 return cxstring::createRef("packed");
3447 }
3448
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003449 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003450}
3451
3452CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3453 unsigned pieceIndex,
3454 unsigned options) {
3455 if (clang_Cursor_isNull(C))
3456 return clang_getNullRange();
3457
3458 ASTContext &Ctx = getCursorContext(C);
3459
3460 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003461 const Stmt *S = getCursorStmt(C);
3462 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003463 if (pieceIndex > 0)
3464 return clang_getNullRange();
3465 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3466 }
3467
3468 return clang_getNullRange();
3469 }
3470
3471 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003472 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003473 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3474 if (pieceIndex >= ME->getNumSelectorLocs())
3475 return clang_getNullRange();
3476 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3477 }
3478 }
3479
3480 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3481 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003482 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003483 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3484 if (pieceIndex >= MD->getNumSelectorLocs())
3485 return clang_getNullRange();
3486 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3487 }
3488 }
3489
3490 if (C.kind == CXCursor_ObjCCategoryDecl ||
3491 C.kind == CXCursor_ObjCCategoryImplDecl) {
3492 if (pieceIndex > 0)
3493 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003494 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003495 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3496 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003497 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003498 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3499 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3500 }
3501
3502 if (C.kind == CXCursor_ModuleImportDecl) {
3503 if (pieceIndex > 0)
3504 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003505 if (const ImportDecl *ImportD =
3506 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003507 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3508 if (!Locs.empty())
3509 return cxloc::translateSourceRange(Ctx,
3510 SourceRange(Locs.front(), Locs.back()));
3511 }
3512 return clang_getNullRange();
3513 }
3514
3515 // FIXME: A CXCursor_InclusionDirective should give the location of the
3516 // filename, but we don't keep track of this.
3517
3518 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3519 // but we don't keep track of this.
3520
3521 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3522 // but we don't keep track of this.
3523
3524 // Default handling, give the location of the cursor.
3525
3526 if (pieceIndex > 0)
3527 return clang_getNullRange();
3528
3529 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3530 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3531 return cxloc::translateSourceRange(Ctx, Loc);
3532}
3533
3534CXString clang_getCursorDisplayName(CXCursor C) {
3535 if (!clang_isDeclaration(C.kind))
3536 return clang_getCursorSpelling(C);
3537
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003538 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003539 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003540 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003541
3542 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003543 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003544 D = FunTmpl->getTemplatedDecl();
3545
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003546 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003547 SmallString<64> Str;
3548 llvm::raw_svector_ostream OS(Str);
3549 OS << *Function;
3550 if (Function->getPrimaryTemplate())
3551 OS << "<>";
3552 OS << "(";
3553 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3554 if (I)
3555 OS << ", ";
3556 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3557 }
3558
3559 if (Function->isVariadic()) {
3560 if (Function->getNumParams())
3561 OS << ", ";
3562 OS << "...";
3563 }
3564 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003565 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003566 }
3567
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003568 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003569 SmallString<64> Str;
3570 llvm::raw_svector_ostream OS(Str);
3571 OS << *ClassTemplate;
3572 OS << "<";
3573 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3574 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3575 if (I)
3576 OS << ", ";
3577
3578 NamedDecl *Param = Params->getParam(I);
3579 if (Param->getIdentifier()) {
3580 OS << Param->getIdentifier()->getName();
3581 continue;
3582 }
3583
3584 // There is no parameter name, which makes this tricky. Try to come up
3585 // with something useful that isn't too long.
3586 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3587 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3588 else if (NonTypeTemplateParmDecl *NTTP
3589 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3590 OS << NTTP->getType().getAsString(Policy);
3591 else
3592 OS << "template<...> class";
3593 }
3594
3595 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003596 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003597 }
3598
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003599 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003600 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3601 // If the type was explicitly written, use that.
3602 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003603 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003604
Benjamin Kramer9170e912013-02-22 15:46:01 +00003605 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003606 llvm::raw_svector_ostream OS(Str);
3607 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003608 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003609 ClassSpec->getTemplateArgs().data(),
3610 ClassSpec->getTemplateArgs().size(),
3611 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003612 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003613 }
3614
3615 return clang_getCursorSpelling(C);
3616}
3617
3618CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3619 switch (Kind) {
3620 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003621 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003622 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003623 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003624 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003625 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003626 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003627 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003628 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003629 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003630 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003631 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003632 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003633 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003635 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003637 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003641 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003643 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003645 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003647 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003651 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003653 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003655 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003659 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003663 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003665 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003673 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003748 case CXCursor_ObjCSelfExpr:
3749 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003866 case CXCursor_PackedAttr:
3867 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003916 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003917 return cxstring::createRef("OMPParallelDirective");
3918 case CXCursor_OMPSimdDirective:
3919 return cxstring::createRef("OMPSimdDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 }
3921
3922 llvm_unreachable("Unhandled CXCursorKind");
3923}
3924
3925struct GetCursorData {
3926 SourceLocation TokenBeginLoc;
3927 bool PointsAtMacroArgExpansion;
3928 bool VisitedObjCPropertyImplDecl;
3929 SourceLocation VisitedDeclaratorDeclStartLoc;
3930 CXCursor &BestCursor;
3931
3932 GetCursorData(SourceManager &SM,
3933 SourceLocation tokenBegin, CXCursor &outputCursor)
3934 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3935 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3936 VisitedObjCPropertyImplDecl = false;
3937 }
3938};
3939
3940static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3941 CXCursor parent,
3942 CXClientData client_data) {
3943 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3944 CXCursor *BestCursor = &Data->BestCursor;
3945
3946 // If we point inside a macro argument we should provide info of what the
3947 // token is so use the actual cursor, don't replace it with a macro expansion
3948 // cursor.
3949 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3950 return CXChildVisit_Recurse;
3951
3952 if (clang_isDeclaration(cursor.kind)) {
3953 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003954 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3956 if (MD->isImplicit())
3957 return CXChildVisit_Break;
3958
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003959 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003960 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3961 // Check that when we have multiple @class references in the same line,
3962 // that later ones do not override the previous ones.
3963 // If we have:
3964 // @class Foo, Bar;
3965 // source ranges for both start at '@', so 'Bar' will end up overriding
3966 // 'Foo' even though the cursor location was at 'Foo'.
3967 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3968 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003969 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3971 if (PrevID != ID &&
3972 !PrevID->isThisDeclarationADefinition() &&
3973 !ID->isThisDeclarationADefinition())
3974 return CXChildVisit_Break;
3975 }
3976
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003977 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3979 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3980 // Check that when we have multiple declarators in the same line,
3981 // that later ones do not override the previous ones.
3982 // If we have:
3983 // int Foo, Bar;
3984 // source ranges for both start at 'int', so 'Bar' will end up overriding
3985 // 'Foo' even though the cursor location was at 'Foo'.
3986 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3987 return CXChildVisit_Break;
3988 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3989
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003990 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3992 (void)PropImp;
3993 // Check that when we have multiple @synthesize in the same line,
3994 // that later ones do not override the previous ones.
3995 // If we have:
3996 // @synthesize Foo, Bar;
3997 // source ranges for both start at '@', so 'Bar' will end up overriding
3998 // 'Foo' even though the cursor location was at 'Foo'.
3999 if (Data->VisitedObjCPropertyImplDecl)
4000 return CXChildVisit_Break;
4001 Data->VisitedObjCPropertyImplDecl = true;
4002 }
4003 }
4004
4005 if (clang_isExpression(cursor.kind) &&
4006 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004007 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004008 // Avoid having the cursor of an expression replace the declaration cursor
4009 // when the expression source range overlaps the declaration range.
4010 // This can happen for C++ constructor expressions whose range generally
4011 // include the variable declaration, e.g.:
4012 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4013 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4014 D->getLocation() == Data->TokenBeginLoc)
4015 return CXChildVisit_Break;
4016 }
4017 }
4018
4019 // If our current best cursor is the construction of a temporary object,
4020 // don't replace that cursor with a type reference, because we want
4021 // clang_getCursor() to point at the constructor.
4022 if (clang_isExpression(BestCursor->kind) &&
4023 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4024 cursor.kind == CXCursor_TypeRef) {
4025 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4026 // as having the actual point on the type reference.
4027 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4028 return CXChildVisit_Recurse;
4029 }
4030
4031 *BestCursor = cursor;
4032 return CXChildVisit_Recurse;
4033}
4034
4035CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004036 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004037 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004038 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004039 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004040
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004041 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004042 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4043
4044 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4045 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4046
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004047 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 CXFile SearchFile;
4049 unsigned SearchLine, SearchColumn;
4050 CXFile ResultFile;
4051 unsigned ResultLine, ResultColumn;
4052 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4053 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4054 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4055
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004056 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4057 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 &ResultColumn, 0);
4059 SearchFileName = clang_getFileName(SearchFile);
4060 ResultFileName = clang_getFileName(ResultFile);
4061 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4062 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004063 *Log << llvm::format("(%s:%d:%d) = %s",
4064 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4065 clang_getCString(KindSpelling))
4066 << llvm::format("(%s:%d:%d):%s%s",
4067 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4068 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004069 clang_disposeString(SearchFileName);
4070 clang_disposeString(ResultFileName);
4071 clang_disposeString(KindSpelling);
4072 clang_disposeString(USR);
4073
4074 CXCursor Definition = clang_getCursorDefinition(Result);
4075 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4076 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4077 CXString DefinitionKindSpelling
4078 = clang_getCursorKindSpelling(Definition.kind);
4079 CXFile DefinitionFile;
4080 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004081 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 &DefinitionLine, &DefinitionColumn, 0);
4083 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004084 *Log << llvm::format(" -> %s(%s:%d:%d)",
4085 clang_getCString(DefinitionKindSpelling),
4086 clang_getCString(DefinitionFileName),
4087 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004088 clang_disposeString(DefinitionFileName);
4089 clang_disposeString(DefinitionKindSpelling);
4090 }
4091 }
4092
4093 return Result;
4094}
4095
4096CXCursor clang_getNullCursor(void) {
4097 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4098}
4099
4100unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004101 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4102 // can't set consistently. For example, when visiting a DeclStmt we will set
4103 // it but we don't set it on the result of clang_getCursorDefinition for
4104 // a reference of the same declaration.
4105 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4106 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4107 // to provide that kind of info.
4108 if (clang_isDeclaration(X.kind))
4109 X.data[1] = 0;
4110 if (clang_isDeclaration(Y.kind))
4111 Y.data[1] = 0;
4112
Guy Benyei11169dd2012-12-18 14:30:41 +00004113 return X == Y;
4114}
4115
4116unsigned clang_hashCursor(CXCursor C) {
4117 unsigned Index = 0;
4118 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4119 Index = 1;
4120
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004121 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004122 std::make_pair(C.kind, C.data[Index]));
4123}
4124
4125unsigned clang_isInvalid(enum CXCursorKind K) {
4126 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4127}
4128
4129unsigned clang_isDeclaration(enum CXCursorKind K) {
4130 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4131 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4132}
4133
4134unsigned clang_isReference(enum CXCursorKind K) {
4135 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4136}
4137
4138unsigned clang_isExpression(enum CXCursorKind K) {
4139 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4140}
4141
4142unsigned clang_isStatement(enum CXCursorKind K) {
4143 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4144}
4145
4146unsigned clang_isAttribute(enum CXCursorKind K) {
4147 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4148}
4149
4150unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4151 return K == CXCursor_TranslationUnit;
4152}
4153
4154unsigned clang_isPreprocessing(enum CXCursorKind K) {
4155 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4156}
4157
4158unsigned clang_isUnexposed(enum CXCursorKind K) {
4159 switch (K) {
4160 case CXCursor_UnexposedDecl:
4161 case CXCursor_UnexposedExpr:
4162 case CXCursor_UnexposedStmt:
4163 case CXCursor_UnexposedAttr:
4164 return true;
4165 default:
4166 return false;
4167 }
4168}
4169
4170CXCursorKind clang_getCursorKind(CXCursor C) {
4171 return C.kind;
4172}
4173
4174CXSourceLocation clang_getCursorLocation(CXCursor C) {
4175 if (clang_isReference(C.kind)) {
4176 switch (C.kind) {
4177 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004178 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004179 = getCursorObjCSuperClassRef(C);
4180 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4181 }
4182
4183 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004184 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004185 = getCursorObjCProtocolRef(C);
4186 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4187 }
4188
4189 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004190 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 = getCursorObjCClassRef(C);
4192 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4193 }
4194
4195 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004196 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4198 }
4199
4200 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004201 std::pair<const TemplateDecl *, SourceLocation> P =
4202 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4204 }
4205
4206 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004207 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4209 }
4210
4211 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004212 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004213 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4214 }
4215
4216 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004217 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4219 }
4220
4221 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004222 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004223 if (!BaseSpec)
4224 return clang_getNullLocation();
4225
4226 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4227 return cxloc::translateSourceLocation(getCursorContext(C),
4228 TSInfo->getTypeLoc().getBeginLoc());
4229
4230 return cxloc::translateSourceLocation(getCursorContext(C),
4231 BaseSpec->getLocStart());
4232 }
4233
4234 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004235 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004236 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4237 }
4238
4239 case CXCursor_OverloadedDeclRef:
4240 return cxloc::translateSourceLocation(getCursorContext(C),
4241 getCursorOverloadedDeclRef(C).second);
4242
4243 default:
4244 // FIXME: Need a way to enumerate all non-reference cases.
4245 llvm_unreachable("Missed a reference kind");
4246 }
4247 }
4248
4249 if (clang_isExpression(C.kind))
4250 return cxloc::translateSourceLocation(getCursorContext(C),
4251 getLocationFromExpr(getCursorExpr(C)));
4252
4253 if (clang_isStatement(C.kind))
4254 return cxloc::translateSourceLocation(getCursorContext(C),
4255 getCursorStmt(C)->getLocStart());
4256
4257 if (C.kind == CXCursor_PreprocessingDirective) {
4258 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4259 return cxloc::translateSourceLocation(getCursorContext(C), L);
4260 }
4261
4262 if (C.kind == CXCursor_MacroExpansion) {
4263 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004264 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004265 return cxloc::translateSourceLocation(getCursorContext(C), L);
4266 }
4267
4268 if (C.kind == CXCursor_MacroDefinition) {
4269 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4270 return cxloc::translateSourceLocation(getCursorContext(C), L);
4271 }
4272
4273 if (C.kind == CXCursor_InclusionDirective) {
4274 SourceLocation L
4275 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4276 return cxloc::translateSourceLocation(getCursorContext(C), L);
4277 }
4278
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004279 if (clang_isAttribute(C.kind)) {
4280 SourceLocation L
4281 = cxcursor::getCursorAttr(C)->getLocation();
4282 return cxloc::translateSourceLocation(getCursorContext(C), L);
4283 }
4284
Guy Benyei11169dd2012-12-18 14:30:41 +00004285 if (!clang_isDeclaration(C.kind))
4286 return clang_getNullLocation();
4287
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004288 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004289 if (!D)
4290 return clang_getNullLocation();
4291
4292 SourceLocation Loc = D->getLocation();
4293 // FIXME: Multiple variables declared in a single declaration
4294 // currently lack the information needed to correctly determine their
4295 // ranges when accounting for the type-specifier. We use context
4296 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4297 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004298 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004299 if (!cxcursor::isFirstInDeclGroup(C))
4300 Loc = VD->getLocation();
4301 }
4302
4303 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004304 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004305 Loc = MD->getSelectorStartLoc();
4306
4307 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4308}
4309
4310} // end extern "C"
4311
4312CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4313 assert(TU);
4314
4315 // Guard against an invalid SourceLocation, or we may assert in one
4316 // of the following calls.
4317 if (SLoc.isInvalid())
4318 return clang_getNullCursor();
4319
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004320 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004321
4322 // Translate the given source location to make it point at the beginning of
4323 // the token under the cursor.
4324 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4325 CXXUnit->getASTContext().getLangOpts());
4326
4327 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4328 if (SLoc.isValid()) {
4329 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4330 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4331 /*VisitPreprocessorLast=*/true,
4332 /*VisitIncludedEntities=*/false,
4333 SourceLocation(SLoc));
4334 CursorVis.visitFileRegion();
4335 }
4336
4337 return Result;
4338}
4339
4340static SourceRange getRawCursorExtent(CXCursor C) {
4341 if (clang_isReference(C.kind)) {
4342 switch (C.kind) {
4343 case CXCursor_ObjCSuperClassRef:
4344 return getCursorObjCSuperClassRef(C).second;
4345
4346 case CXCursor_ObjCProtocolRef:
4347 return getCursorObjCProtocolRef(C).second;
4348
4349 case CXCursor_ObjCClassRef:
4350 return getCursorObjCClassRef(C).second;
4351
4352 case CXCursor_TypeRef:
4353 return getCursorTypeRef(C).second;
4354
4355 case CXCursor_TemplateRef:
4356 return getCursorTemplateRef(C).second;
4357
4358 case CXCursor_NamespaceRef:
4359 return getCursorNamespaceRef(C).second;
4360
4361 case CXCursor_MemberRef:
4362 return getCursorMemberRef(C).second;
4363
4364 case CXCursor_CXXBaseSpecifier:
4365 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4366
4367 case CXCursor_LabelRef:
4368 return getCursorLabelRef(C).second;
4369
4370 case CXCursor_OverloadedDeclRef:
4371 return getCursorOverloadedDeclRef(C).second;
4372
4373 case CXCursor_VariableRef:
4374 return getCursorVariableRef(C).second;
4375
4376 default:
4377 // FIXME: Need a way to enumerate all non-reference cases.
4378 llvm_unreachable("Missed a reference kind");
4379 }
4380 }
4381
4382 if (clang_isExpression(C.kind))
4383 return getCursorExpr(C)->getSourceRange();
4384
4385 if (clang_isStatement(C.kind))
4386 return getCursorStmt(C)->getSourceRange();
4387
4388 if (clang_isAttribute(C.kind))
4389 return getCursorAttr(C)->getRange();
4390
4391 if (C.kind == CXCursor_PreprocessingDirective)
4392 return cxcursor::getCursorPreprocessingDirective(C);
4393
4394 if (C.kind == CXCursor_MacroExpansion) {
4395 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004396 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004397 return TU->mapRangeFromPreamble(Range);
4398 }
4399
4400 if (C.kind == CXCursor_MacroDefinition) {
4401 ASTUnit *TU = getCursorASTUnit(C);
4402 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4403 return TU->mapRangeFromPreamble(Range);
4404 }
4405
4406 if (C.kind == CXCursor_InclusionDirective) {
4407 ASTUnit *TU = getCursorASTUnit(C);
4408 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4409 return TU->mapRangeFromPreamble(Range);
4410 }
4411
4412 if (C.kind == CXCursor_TranslationUnit) {
4413 ASTUnit *TU = getCursorASTUnit(C);
4414 FileID MainID = TU->getSourceManager().getMainFileID();
4415 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4416 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4417 return SourceRange(Start, End);
4418 }
4419
4420 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004421 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004422 if (!D)
4423 return SourceRange();
4424
4425 SourceRange R = D->getSourceRange();
4426 // FIXME: Multiple variables declared in a single declaration
4427 // currently lack the information needed to correctly determine their
4428 // ranges when accounting for the type-specifier. We use context
4429 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4430 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004431 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004432 if (!cxcursor::isFirstInDeclGroup(C))
4433 R.setBegin(VD->getLocation());
4434 }
4435 return R;
4436 }
4437 return SourceRange();
4438}
4439
4440/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4441/// the decl-specifier-seq for declarations.
4442static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4443 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004444 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004445 if (!D)
4446 return SourceRange();
4447
4448 SourceRange R = D->getSourceRange();
4449
4450 // Adjust the start of the location for declarations preceded by
4451 // declaration specifiers.
4452 SourceLocation StartLoc;
4453 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4454 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4455 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004456 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004457 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4458 StartLoc = TI->getTypeLoc().getLocStart();
4459 }
4460
4461 if (StartLoc.isValid() && R.getBegin().isValid() &&
4462 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4463 R.setBegin(StartLoc);
4464
4465 // FIXME: Multiple variables declared in a single declaration
4466 // currently lack the information needed to correctly determine their
4467 // ranges when accounting for the type-specifier. We use context
4468 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4469 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004470 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004471 if (!cxcursor::isFirstInDeclGroup(C))
4472 R.setBegin(VD->getLocation());
4473 }
4474
4475 return R;
4476 }
4477
4478 return getRawCursorExtent(C);
4479}
4480
4481extern "C" {
4482
4483CXSourceRange clang_getCursorExtent(CXCursor C) {
4484 SourceRange R = getRawCursorExtent(C);
4485 if (R.isInvalid())
4486 return clang_getNullRange();
4487
4488 return cxloc::translateSourceRange(getCursorContext(C), R);
4489}
4490
4491CXCursor clang_getCursorReferenced(CXCursor C) {
4492 if (clang_isInvalid(C.kind))
4493 return clang_getNullCursor();
4494
4495 CXTranslationUnit tu = getCursorTU(C);
4496 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004497 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004498 if (!D)
4499 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004500 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004501 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004502 if (const ObjCPropertyImplDecl *PropImpl =
4503 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004504 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4505 return MakeCXCursor(Property, tu);
4506
4507 return C;
4508 }
4509
4510 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004511 const Expr *E = getCursorExpr(C);
4512 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004513 if (D) {
4514 CXCursor declCursor = MakeCXCursor(D, tu);
4515 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4516 declCursor);
4517 return declCursor;
4518 }
4519
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004520 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004521 return MakeCursorOverloadedDeclRef(Ovl, tu);
4522
4523 return clang_getNullCursor();
4524 }
4525
4526 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004527 const Stmt *S = getCursorStmt(C);
4528 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004529 if (LabelDecl *label = Goto->getLabel())
4530 if (LabelStmt *labelS = label->getStmt())
4531 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4532
4533 return clang_getNullCursor();
4534 }
4535
4536 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004537 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004538 return MakeMacroDefinitionCursor(Def, tu);
4539 }
4540
4541 if (!clang_isReference(C.kind))
4542 return clang_getNullCursor();
4543
4544 switch (C.kind) {
4545 case CXCursor_ObjCSuperClassRef:
4546 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4547
4548 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004549 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4550 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004551 return MakeCXCursor(Def, tu);
4552
4553 return MakeCXCursor(Prot, tu);
4554 }
4555
4556 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004557 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4558 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004559 return MakeCXCursor(Def, tu);
4560
4561 return MakeCXCursor(Class, tu);
4562 }
4563
4564 case CXCursor_TypeRef:
4565 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4566
4567 case CXCursor_TemplateRef:
4568 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4569
4570 case CXCursor_NamespaceRef:
4571 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4572
4573 case CXCursor_MemberRef:
4574 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4575
4576 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004577 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004578 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4579 tu ));
4580 }
4581
4582 case CXCursor_LabelRef:
4583 // FIXME: We end up faking the "parent" declaration here because we
4584 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004585 return MakeCXCursor(getCursorLabelRef(C).first,
4586 cxtu::getASTUnit(tu)->getASTContext()
4587 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004588 tu);
4589
4590 case CXCursor_OverloadedDeclRef:
4591 return C;
4592
4593 case CXCursor_VariableRef:
4594 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4595
4596 default:
4597 // We would prefer to enumerate all non-reference cursor kinds here.
4598 llvm_unreachable("Unhandled reference cursor kind");
4599 }
4600}
4601
4602CXCursor clang_getCursorDefinition(CXCursor C) {
4603 if (clang_isInvalid(C.kind))
4604 return clang_getNullCursor();
4605
4606 CXTranslationUnit TU = getCursorTU(C);
4607
4608 bool WasReference = false;
4609 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4610 C = clang_getCursorReferenced(C);
4611 WasReference = true;
4612 }
4613
4614 if (C.kind == CXCursor_MacroExpansion)
4615 return clang_getCursorReferenced(C);
4616
4617 if (!clang_isDeclaration(C.kind))
4618 return clang_getNullCursor();
4619
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004620 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004621 if (!D)
4622 return clang_getNullCursor();
4623
4624 switch (D->getKind()) {
4625 // Declaration kinds that don't really separate the notions of
4626 // declaration and definition.
4627 case Decl::Namespace:
4628 case Decl::Typedef:
4629 case Decl::TypeAlias:
4630 case Decl::TypeAliasTemplate:
4631 case Decl::TemplateTypeParm:
4632 case Decl::EnumConstant:
4633 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004634 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004635 case Decl::IndirectField:
4636 case Decl::ObjCIvar:
4637 case Decl::ObjCAtDefsField:
4638 case Decl::ImplicitParam:
4639 case Decl::ParmVar:
4640 case Decl::NonTypeTemplateParm:
4641 case Decl::TemplateTemplateParm:
4642 case Decl::ObjCCategoryImpl:
4643 case Decl::ObjCImplementation:
4644 case Decl::AccessSpec:
4645 case Decl::LinkageSpec:
4646 case Decl::ObjCPropertyImpl:
4647 case Decl::FileScopeAsm:
4648 case Decl::StaticAssert:
4649 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004650 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004651 case Decl::Label: // FIXME: Is this right??
4652 case Decl::ClassScopeFunctionSpecialization:
4653 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004654 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004655 return C;
4656
4657 // Declaration kinds that don't make any sense here, but are
4658 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004659 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004660 case Decl::TranslationUnit:
4661 break;
4662
4663 // Declaration kinds for which the definition is not resolvable.
4664 case Decl::UnresolvedUsingTypename:
4665 case Decl::UnresolvedUsingValue:
4666 break;
4667
4668 case Decl::UsingDirective:
4669 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4670 TU);
4671
4672 case Decl::NamespaceAlias:
4673 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4674
4675 case Decl::Enum:
4676 case Decl::Record:
4677 case Decl::CXXRecord:
4678 case Decl::ClassTemplateSpecialization:
4679 case Decl::ClassTemplatePartialSpecialization:
4680 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4681 return MakeCXCursor(Def, TU);
4682 return clang_getNullCursor();
4683
4684 case Decl::Function:
4685 case Decl::CXXMethod:
4686 case Decl::CXXConstructor:
4687 case Decl::CXXDestructor:
4688 case Decl::CXXConversion: {
4689 const FunctionDecl *Def = 0;
4690 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004691 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004692 return clang_getNullCursor();
4693 }
4694
Larisse Voufo39a1e502013-08-06 01:03:05 +00004695 case Decl::Var:
4696 case Decl::VarTemplateSpecialization:
4697 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004698 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004699 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004700 return MakeCXCursor(Def, TU);
4701 return clang_getNullCursor();
4702 }
4703
4704 case Decl::FunctionTemplate: {
4705 const FunctionDecl *Def = 0;
4706 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4707 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4708 return clang_getNullCursor();
4709 }
4710
4711 case Decl::ClassTemplate: {
4712 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4713 ->getDefinition())
4714 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4715 TU);
4716 return clang_getNullCursor();
4717 }
4718
Larisse Voufo39a1e502013-08-06 01:03:05 +00004719 case Decl::VarTemplate: {
4720 if (VarDecl *Def =
4721 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4722 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4723 return clang_getNullCursor();
4724 }
4725
Guy Benyei11169dd2012-12-18 14:30:41 +00004726 case Decl::Using:
4727 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4728 D->getLocation(), TU);
4729
4730 case Decl::UsingShadow:
4731 return clang_getCursorDefinition(
4732 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4733 TU));
4734
4735 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004736 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004737 if (Method->isThisDeclarationADefinition())
4738 return C;
4739
4740 // Dig out the method definition in the associated
4741 // @implementation, if we have it.
4742 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004743 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004744 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4745 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4746 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4747 Method->isInstanceMethod()))
4748 if (Def->isThisDeclarationADefinition())
4749 return MakeCXCursor(Def, TU);
4750
4751 return clang_getNullCursor();
4752 }
4753
4754 case Decl::ObjCCategory:
4755 if (ObjCCategoryImplDecl *Impl
4756 = cast<ObjCCategoryDecl>(D)->getImplementation())
4757 return MakeCXCursor(Impl, TU);
4758 return clang_getNullCursor();
4759
4760 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004761 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004762 return MakeCXCursor(Def, TU);
4763 return clang_getNullCursor();
4764
4765 case Decl::ObjCInterface: {
4766 // There are two notions of a "definition" for an Objective-C
4767 // class: the interface and its implementation. When we resolved a
4768 // reference to an Objective-C class, produce the @interface as
4769 // the definition; when we were provided with the interface,
4770 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004771 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004772 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004773 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004774 return MakeCXCursor(Def, TU);
4775 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4776 return MakeCXCursor(Impl, TU);
4777 return clang_getNullCursor();
4778 }
4779
4780 case Decl::ObjCProperty:
4781 // FIXME: We don't really know where to find the
4782 // ObjCPropertyImplDecls that implement this property.
4783 return clang_getNullCursor();
4784
4785 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004786 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004787 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004788 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004789 return MakeCXCursor(Def, TU);
4790
4791 return clang_getNullCursor();
4792
4793 case Decl::Friend:
4794 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4795 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4796 return clang_getNullCursor();
4797
4798 case Decl::FriendTemplate:
4799 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4800 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4801 return clang_getNullCursor();
4802 }
4803
4804 return clang_getNullCursor();
4805}
4806
4807unsigned clang_isCursorDefinition(CXCursor C) {
4808 if (!clang_isDeclaration(C.kind))
4809 return 0;
4810
4811 return clang_getCursorDefinition(C) == C;
4812}
4813
4814CXCursor clang_getCanonicalCursor(CXCursor C) {
4815 if (!clang_isDeclaration(C.kind))
4816 return C;
4817
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004818 if (const Decl *D = getCursorDecl(C)) {
4819 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004820 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4821 return MakeCXCursor(CatD, getCursorTU(C));
4822
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004823 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4824 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004825 return MakeCXCursor(IFD, getCursorTU(C));
4826
4827 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4828 }
4829
4830 return C;
4831}
4832
4833int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4834 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4835}
4836
4837unsigned clang_getNumOverloadedDecls(CXCursor C) {
4838 if (C.kind != CXCursor_OverloadedDeclRef)
4839 return 0;
4840
4841 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004842 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004843 return E->getNumDecls();
4844
4845 if (OverloadedTemplateStorage *S
4846 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4847 return S->size();
4848
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004849 const Decl *D = Storage.get<const Decl *>();
4850 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004851 return Using->shadow_size();
4852
4853 return 0;
4854}
4855
4856CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4857 if (cursor.kind != CXCursor_OverloadedDeclRef)
4858 return clang_getNullCursor();
4859
4860 if (index >= clang_getNumOverloadedDecls(cursor))
4861 return clang_getNullCursor();
4862
4863 CXTranslationUnit TU = getCursorTU(cursor);
4864 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004865 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004866 return MakeCXCursor(E->decls_begin()[index], TU);
4867
4868 if (OverloadedTemplateStorage *S
4869 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4870 return MakeCXCursor(S->begin()[index], TU);
4871
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004872 const Decl *D = Storage.get<const Decl *>();
4873 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004874 // FIXME: This is, unfortunately, linear time.
4875 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4876 std::advance(Pos, index);
4877 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4878 }
4879
4880 return clang_getNullCursor();
4881}
4882
4883void clang_getDefinitionSpellingAndExtent(CXCursor C,
4884 const char **startBuf,
4885 const char **endBuf,
4886 unsigned *startLine,
4887 unsigned *startColumn,
4888 unsigned *endLine,
4889 unsigned *endColumn) {
4890 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004891 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004892 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4893
4894 SourceManager &SM = FD->getASTContext().getSourceManager();
4895 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4896 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4897 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4898 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4899 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4900 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4901}
4902
4903
4904CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4905 unsigned PieceIndex) {
4906 RefNamePieces Pieces;
4907
4908 switch (C.kind) {
4909 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004910 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004911 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4912 E->getQualifierLoc().getSourceRange());
4913 break;
4914
4915 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004916 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004917 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4918 E->getQualifierLoc().getSourceRange(),
4919 E->getOptionalExplicitTemplateArgs());
4920 break;
4921
4922 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004923 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004924 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004925 const Expr *Callee = OCE->getCallee();
4926 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004927 Callee = ICE->getSubExpr();
4928
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004929 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004930 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4931 DRE->getQualifierLoc().getSourceRange());
4932 }
4933 break;
4934
4935 default:
4936 break;
4937 }
4938
4939 if (Pieces.empty()) {
4940 if (PieceIndex == 0)
4941 return clang_getCursorExtent(C);
4942 } else if (PieceIndex < Pieces.size()) {
4943 SourceRange R = Pieces[PieceIndex];
4944 if (R.isValid())
4945 return cxloc::translateSourceRange(getCursorContext(C), R);
4946 }
4947
4948 return clang_getNullRange();
4949}
4950
4951void clang_enableStackTraces(void) {
4952 llvm::sys::PrintStackTraceOnErrorSignal();
4953}
4954
4955void clang_executeOnThread(void (*fn)(void*), void *user_data,
4956 unsigned stack_size) {
4957 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4958}
4959
4960} // end: extern "C"
4961
4962//===----------------------------------------------------------------------===//
4963// Token-based Operations.
4964//===----------------------------------------------------------------------===//
4965
4966/* CXToken layout:
4967 * int_data[0]: a CXTokenKind
4968 * int_data[1]: starting token location
4969 * int_data[2]: token length
4970 * int_data[3]: reserved
4971 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4972 * otherwise unused.
4973 */
4974extern "C" {
4975
4976CXTokenKind clang_getTokenKind(CXToken CXTok) {
4977 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4978}
4979
4980CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4981 switch (clang_getTokenKind(CXTok)) {
4982 case CXToken_Identifier:
4983 case CXToken_Keyword:
4984 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004985 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004986 ->getNameStart());
4987
4988 case CXToken_Literal: {
4989 // We have stashed the starting pointer in the ptr_data field. Use it.
4990 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004991 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004992 }
4993
4994 case CXToken_Punctuation:
4995 case CXToken_Comment:
4996 break;
4997 }
4998
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004999 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005000 LOG_BAD_TU(TU);
5001 return cxstring::createEmpty();
5002 }
5003
Guy Benyei11169dd2012-12-18 14:30:41 +00005004 // We have to find the starting buffer pointer the hard way, by
5005 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005006 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005007 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005008 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005009
5010 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5011 std::pair<FileID, unsigned> LocInfo
5012 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5013 bool Invalid = false;
5014 StringRef Buffer
5015 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5016 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005017 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005018
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005019 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005020}
5021
5022CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005023 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005024 LOG_BAD_TU(TU);
5025 return clang_getNullLocation();
5026 }
5027
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005028 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005029 if (!CXXUnit)
5030 return clang_getNullLocation();
5031
5032 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5033 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5034}
5035
5036CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005037 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005038 LOG_BAD_TU(TU);
5039 return clang_getNullRange();
5040 }
5041
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005042 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005043 if (!CXXUnit)
5044 return clang_getNullRange();
5045
5046 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5047 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5048}
5049
5050static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5051 SmallVectorImpl<CXToken> &CXTokens) {
5052 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5053 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005054 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005055 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005056 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005057
5058 // Cannot tokenize across files.
5059 if (BeginLocInfo.first != EndLocInfo.first)
5060 return;
5061
5062 // Create a lexer
5063 bool Invalid = false;
5064 StringRef Buffer
5065 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5066 if (Invalid)
5067 return;
5068
5069 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5070 CXXUnit->getASTContext().getLangOpts(),
5071 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5072 Lex.SetCommentRetentionState(true);
5073
5074 // Lex tokens until we hit the end of the range.
5075 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5076 Token Tok;
5077 bool previousWasAt = false;
5078 do {
5079 // Lex the next token
5080 Lex.LexFromRawLexer(Tok);
5081 if (Tok.is(tok::eof))
5082 break;
5083
5084 // Initialize the CXToken.
5085 CXToken CXTok;
5086
5087 // - Common fields
5088 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5089 CXTok.int_data[2] = Tok.getLength();
5090 CXTok.int_data[3] = 0;
5091
5092 // - Kind-specific fields
5093 if (Tok.isLiteral()) {
5094 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005095 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005096 } else if (Tok.is(tok::raw_identifier)) {
5097 // Lookup the identifier to determine whether we have a keyword.
5098 IdentifierInfo *II
5099 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5100
5101 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5102 CXTok.int_data[0] = CXToken_Keyword;
5103 }
5104 else {
5105 CXTok.int_data[0] = Tok.is(tok::identifier)
5106 ? CXToken_Identifier
5107 : CXToken_Keyword;
5108 }
5109 CXTok.ptr_data = II;
5110 } else if (Tok.is(tok::comment)) {
5111 CXTok.int_data[0] = CXToken_Comment;
5112 CXTok.ptr_data = 0;
5113 } else {
5114 CXTok.int_data[0] = CXToken_Punctuation;
5115 CXTok.ptr_data = 0;
5116 }
5117 CXTokens.push_back(CXTok);
5118 previousWasAt = Tok.is(tok::at);
5119 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5120}
5121
5122void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5123 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005124 LOG_FUNC_SECTION {
5125 *Log << TU << ' ' << Range;
5126 }
5127
Guy Benyei11169dd2012-12-18 14:30:41 +00005128 if (Tokens)
5129 *Tokens = 0;
5130 if (NumTokens)
5131 *NumTokens = 0;
5132
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005133 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005134 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005135 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005136 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005137
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005138 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005139 if (!CXXUnit || !Tokens || !NumTokens)
5140 return;
5141
5142 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5143
5144 SourceRange R = cxloc::translateCXSourceRange(Range);
5145 if (R.isInvalid())
5146 return;
5147
5148 SmallVector<CXToken, 32> CXTokens;
5149 getTokens(CXXUnit, R, CXTokens);
5150
5151 if (CXTokens.empty())
5152 return;
5153
5154 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5155 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5156 *NumTokens = CXTokens.size();
5157}
5158
5159void clang_disposeTokens(CXTranslationUnit TU,
5160 CXToken *Tokens, unsigned NumTokens) {
5161 free(Tokens);
5162}
5163
5164} // end: extern "C"
5165
5166//===----------------------------------------------------------------------===//
5167// Token annotation APIs.
5168//===----------------------------------------------------------------------===//
5169
Guy Benyei11169dd2012-12-18 14:30:41 +00005170static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5171 CXCursor parent,
5172 CXClientData client_data);
5173static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5174 CXClientData client_data);
5175
5176namespace {
5177class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005178 CXToken *Tokens;
5179 CXCursor *Cursors;
5180 unsigned NumTokens;
5181 unsigned TokIdx;
5182 unsigned PreprocessingTokIdx;
5183 CursorVisitor AnnotateVis;
5184 SourceManager &SrcMgr;
5185 bool HasContextSensitiveKeywords;
5186
5187 struct PostChildrenInfo {
5188 CXCursor Cursor;
5189 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005190 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005191 unsigned BeforeChildrenTokenIdx;
5192 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005193 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005194
5195 CXToken &getTok(unsigned Idx) {
5196 assert(Idx < NumTokens);
5197 return Tokens[Idx];
5198 }
5199 const CXToken &getTok(unsigned Idx) const {
5200 assert(Idx < NumTokens);
5201 return Tokens[Idx];
5202 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005203 bool MoreTokens() const { return TokIdx < NumTokens; }
5204 unsigned NextToken() const { return TokIdx; }
5205 void AdvanceToken() { ++TokIdx; }
5206 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005207 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005208 }
5209 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005210 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005211 }
5212 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005213 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005214 }
5215
5216 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005217 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 SourceRange);
5219
5220public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005221 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005222 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005223 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005225 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005226 AnnotateTokensVisitor, this,
5227 /*VisitPreprocessorLast=*/true,
5228 /*VisitIncludedEntities=*/false,
5229 RegionOfInterest,
5230 /*VisitDeclsOnly=*/false,
5231 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005232 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005233 HasContextSensitiveKeywords(false) { }
5234
5235 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5236 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5237 bool postVisitChildren(CXCursor cursor);
5238 void AnnotateTokens();
5239
5240 /// \brief Determine whether the annotator saw any cursors that have
5241 /// context-sensitive keywords.
5242 bool hasContextSensitiveKeywords() const {
5243 return HasContextSensitiveKeywords;
5244 }
5245
5246 ~AnnotateTokensWorker() {
5247 assert(PostChildrenInfos.empty());
5248 }
5249};
5250}
5251
5252void AnnotateTokensWorker::AnnotateTokens() {
5253 // Walk the AST within the region of interest, annotating tokens
5254 // along the way.
5255 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005256}
Guy Benyei11169dd2012-12-18 14:30:41 +00005257
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005258static inline void updateCursorAnnotation(CXCursor &Cursor,
5259 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005260 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005261 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005262 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005263}
5264
5265/// \brief It annotates and advances tokens with a cursor until the comparison
5266//// between the cursor location and the source range is the same as
5267/// \arg compResult.
5268///
5269/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5270/// Pass RangeOverlap to annotate tokens inside a range.
5271void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5272 RangeComparisonResult compResult,
5273 SourceRange range) {
5274 while (MoreTokens()) {
5275 const unsigned I = NextToken();
5276 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005277 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5278 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005279
5280 SourceLocation TokLoc = GetTokenLoc(I);
5281 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005282 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005283 AdvanceToken();
5284 continue;
5285 }
5286 break;
5287 }
5288}
5289
5290/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005291/// \returns true if it advanced beyond all macro tokens, false otherwise.
5292bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005293 CXCursor updateC,
5294 RangeComparisonResult compResult,
5295 SourceRange range) {
5296 assert(MoreTokens());
5297 assert(isFunctionMacroToken(NextToken()) &&
5298 "Should be called only for macro arg tokens");
5299
5300 // This works differently than annotateAndAdvanceTokens; because expanded
5301 // macro arguments can have arbitrary translation-unit source order, we do not
5302 // advance the token index one by one until a token fails the range test.
5303 // We only advance once past all of the macro arg tokens if all of them
5304 // pass the range test. If one of them fails we keep the token index pointing
5305 // at the start of the macro arg tokens so that the failing token will be
5306 // annotated by a subsequent annotation try.
5307
5308 bool atLeastOneCompFail = false;
5309
5310 unsigned I = NextToken();
5311 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5312 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5313 if (TokLoc.isFileID())
5314 continue; // not macro arg token, it's parens or comma.
5315 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5316 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5317 Cursors[I] = updateC;
5318 } else
5319 atLeastOneCompFail = true;
5320 }
5321
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005322 if (atLeastOneCompFail)
5323 return false;
5324
5325 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5326 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005327}
5328
5329enum CXChildVisitResult
5330AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005331 SourceRange cursorRange = getRawCursorExtent(cursor);
5332 if (cursorRange.isInvalid())
5333 return CXChildVisit_Recurse;
5334
5335 if (!HasContextSensitiveKeywords) {
5336 // Objective-C properties can have context-sensitive keywords.
5337 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005338 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005339 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5340 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5341 }
5342 // Objective-C methods can have context-sensitive keywords.
5343 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5344 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005345 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005346 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5347 if (Method->getObjCDeclQualifier())
5348 HasContextSensitiveKeywords = true;
5349 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005350 for (const auto *P : Method->params()) {
5351 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005352 HasContextSensitiveKeywords = true;
5353 break;
5354 }
5355 }
5356 }
5357 }
5358 }
5359 // C++ methods can have context-sensitive keywords.
5360 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005361 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005362 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5363 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5364 HasContextSensitiveKeywords = true;
5365 }
5366 }
5367 // C++ classes can have context-sensitive keywords.
5368 else if (cursor.kind == CXCursor_StructDecl ||
5369 cursor.kind == CXCursor_ClassDecl ||
5370 cursor.kind == CXCursor_ClassTemplate ||
5371 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005372 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005373 if (D->hasAttr<FinalAttr>())
5374 HasContextSensitiveKeywords = true;
5375 }
5376 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005377
5378 // Don't override a property annotation with its getter/setter method.
5379 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5380 parent.kind == CXCursor_ObjCPropertyDecl)
5381 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005382
5383 if (clang_isPreprocessing(cursor.kind)) {
5384 // Items in the preprocessing record are kept separate from items in
5385 // declarations, so we keep a separate token index.
5386 unsigned SavedTokIdx = TokIdx;
5387 TokIdx = PreprocessingTokIdx;
5388
5389 // Skip tokens up until we catch up to the beginning of the preprocessing
5390 // entry.
5391 while (MoreTokens()) {
5392 const unsigned I = NextToken();
5393 SourceLocation TokLoc = GetTokenLoc(I);
5394 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5395 case RangeBefore:
5396 AdvanceToken();
5397 continue;
5398 case RangeAfter:
5399 case RangeOverlap:
5400 break;
5401 }
5402 break;
5403 }
5404
5405 // Look at all of the tokens within this range.
5406 while (MoreTokens()) {
5407 const unsigned I = NextToken();
5408 SourceLocation TokLoc = GetTokenLoc(I);
5409 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5410 case RangeBefore:
5411 llvm_unreachable("Infeasible");
5412 case RangeAfter:
5413 break;
5414 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005415 // For macro expansions, just note where the beginning of the macro
5416 // expansion occurs.
5417 if (cursor.kind == CXCursor_MacroExpansion) {
5418 if (TokLoc == cursorRange.getBegin())
5419 Cursors[I] = cursor;
5420 AdvanceToken();
5421 break;
5422 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005423 // We may have already annotated macro names inside macro definitions.
5424 if (Cursors[I].kind != CXCursor_MacroExpansion)
5425 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005426 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005427 continue;
5428 }
5429 break;
5430 }
5431
5432 // Save the preprocessing token index; restore the non-preprocessing
5433 // token index.
5434 PreprocessingTokIdx = TokIdx;
5435 TokIdx = SavedTokIdx;
5436 return CXChildVisit_Recurse;
5437 }
5438
5439 if (cursorRange.isInvalid())
5440 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005441
5442 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005443 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005444 const enum CXCursorKind K = clang_getCursorKind(parent);
5445 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005446 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5447 // Attributes are annotated out-of-order, skip tokens until we reach it.
5448 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005449 ? clang_getNullCursor() : parent;
5450
5451 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5452
5453 // Avoid having the cursor of an expression "overwrite" the annotation of the
5454 // variable declaration that it belongs to.
5455 // This can happen for C++ constructor expressions whose range generally
5456 // include the variable declaration, e.g.:
5457 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005458 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005459 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005460 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005461 const unsigned I = NextToken();
5462 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5463 E->getLocStart() == D->getLocation() &&
5464 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005465 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005466 AdvanceToken();
5467 }
5468 }
5469 }
5470
5471 // Before recursing into the children keep some state that we are going
5472 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5473 // extra work after the child nodes are visited.
5474 // Note that we don't call VisitChildren here to avoid traversing statements
5475 // code-recursively which can blow the stack.
5476
5477 PostChildrenInfo Info;
5478 Info.Cursor = cursor;
5479 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005480 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005481 Info.BeforeChildrenTokenIdx = NextToken();
5482 PostChildrenInfos.push_back(Info);
5483
5484 return CXChildVisit_Recurse;
5485}
5486
5487bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5488 if (PostChildrenInfos.empty())
5489 return false;
5490 const PostChildrenInfo &Info = PostChildrenInfos.back();
5491 if (!clang_equalCursors(Info.Cursor, cursor))
5492 return false;
5493
5494 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5495 const unsigned AfterChildren = NextToken();
5496 SourceRange cursorRange = Info.CursorRange;
5497
5498 // Scan the tokens that are at the end of the cursor, but are not captured
5499 // but the child cursors.
5500 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5501
5502 // Scan the tokens that are at the beginning of the cursor, but are not
5503 // capture by the child cursors.
5504 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5505 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5506 break;
5507
5508 Cursors[I] = cursor;
5509 }
5510
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005511 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5512 // encountered the attribute cursor.
5513 if (clang_isAttribute(cursor.kind))
5514 TokIdx = Info.BeforeReachingCursorIdx;
5515
Guy Benyei11169dd2012-12-18 14:30:41 +00005516 PostChildrenInfos.pop_back();
5517 return false;
5518}
5519
5520static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5521 CXCursor parent,
5522 CXClientData client_data) {
5523 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5524}
5525
5526static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5527 CXClientData client_data) {
5528 return static_cast<AnnotateTokensWorker*>(client_data)->
5529 postVisitChildren(cursor);
5530}
5531
5532namespace {
5533
5534/// \brief Uses the macro expansions in the preprocessing record to find
5535/// and mark tokens that are macro arguments. This info is used by the
5536/// AnnotateTokensWorker.
5537class MarkMacroArgTokensVisitor {
5538 SourceManager &SM;
5539 CXToken *Tokens;
5540 unsigned NumTokens;
5541 unsigned CurIdx;
5542
5543public:
5544 MarkMacroArgTokensVisitor(SourceManager &SM,
5545 CXToken *tokens, unsigned numTokens)
5546 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5547
5548 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5549 if (cursor.kind != CXCursor_MacroExpansion)
5550 return CXChildVisit_Continue;
5551
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005552 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005553 if (macroRange.getBegin() == macroRange.getEnd())
5554 return CXChildVisit_Continue; // it's not a function macro.
5555
5556 for (; CurIdx < NumTokens; ++CurIdx) {
5557 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5558 macroRange.getBegin()))
5559 break;
5560 }
5561
5562 if (CurIdx == NumTokens)
5563 return CXChildVisit_Break;
5564
5565 for (; CurIdx < NumTokens; ++CurIdx) {
5566 SourceLocation tokLoc = getTokenLoc(CurIdx);
5567 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5568 break;
5569
5570 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5571 }
5572
5573 if (CurIdx == NumTokens)
5574 return CXChildVisit_Break;
5575
5576 return CXChildVisit_Continue;
5577 }
5578
5579private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005580 CXToken &getTok(unsigned Idx) {
5581 assert(Idx < NumTokens);
5582 return Tokens[Idx];
5583 }
5584 const CXToken &getTok(unsigned Idx) const {
5585 assert(Idx < NumTokens);
5586 return Tokens[Idx];
5587 }
5588
Guy Benyei11169dd2012-12-18 14:30:41 +00005589 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005590 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005591 }
5592
5593 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5594 // The third field is reserved and currently not used. Use it here
5595 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005596 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005597 }
5598};
5599
5600} // end anonymous namespace
5601
5602static CXChildVisitResult
5603MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5604 CXClientData client_data) {
5605 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5606 parent);
5607}
5608
5609namespace {
5610 struct clang_annotateTokens_Data {
5611 CXTranslationUnit TU;
5612 ASTUnit *CXXUnit;
5613 CXToken *Tokens;
5614 unsigned NumTokens;
5615 CXCursor *Cursors;
5616 };
5617}
5618
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005619/// \brief Used by \c annotatePreprocessorTokens.
5620/// \returns true if lexing was finished, false otherwise.
5621static bool lexNext(Lexer &Lex, Token &Tok,
5622 unsigned &NextIdx, unsigned NumTokens) {
5623 if (NextIdx >= NumTokens)
5624 return true;
5625
5626 ++NextIdx;
5627 Lex.LexFromRawLexer(Tok);
5628 if (Tok.is(tok::eof))
5629 return true;
5630
5631 return false;
5632}
5633
Guy Benyei11169dd2012-12-18 14:30:41 +00005634static void annotatePreprocessorTokens(CXTranslationUnit TU,
5635 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005636 CXCursor *Cursors,
5637 CXToken *Tokens,
5638 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005639 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005640
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005641 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005642 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5643 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005644 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005645 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005646 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005647
5648 if (BeginLocInfo.first != EndLocInfo.first)
5649 return;
5650
5651 StringRef Buffer;
5652 bool Invalid = false;
5653 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5654 if (Buffer.empty() || Invalid)
5655 return;
5656
5657 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5658 CXXUnit->getASTContext().getLangOpts(),
5659 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5660 Buffer.end());
5661 Lex.SetCommentRetentionState(true);
5662
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005663 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005664 // Lex tokens in raw mode until we hit the end of the range, to avoid
5665 // entering #includes or expanding macros.
5666 while (true) {
5667 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005668 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5669 break;
5670 unsigned TokIdx = NextIdx-1;
5671 assert(Tok.getLocation() ==
5672 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005673
5674 reprocess:
5675 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005676 // We have found a preprocessing directive. Annotate the tokens
5677 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005678 //
5679 // FIXME: Some simple tests here could identify macro definitions and
5680 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005681
5682 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005683 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5684 break;
5685
5686 MacroInfo *MI = 0;
5687 if (Tok.is(tok::raw_identifier) &&
5688 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5689 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5690 break;
5691
5692 if (Tok.is(tok::raw_identifier)) {
5693 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5694 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5695 SourceLocation MappedTokLoc =
5696 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5697 MI = getMacroInfo(II, MappedTokLoc, TU);
5698 }
5699 }
5700
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005701 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005702 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005703 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5704 finished = true;
5705 break;
5706 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005707 // If we are in a macro definition, check if the token was ever a
5708 // macro name and annotate it if that's the case.
5709 if (MI) {
5710 SourceLocation SaveLoc = Tok.getLocation();
5711 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5712 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5713 Tok.setLocation(SaveLoc);
5714 if (MacroDef)
5715 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5716 Tok.getLocation(), TU);
5717 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005718 } while (!Tok.isAtStartOfLine());
5719
5720 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5721 assert(TokIdx <= LastIdx);
5722 SourceLocation EndLoc =
5723 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5724 CXCursor Cursor =
5725 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5726
5727 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005728 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005729
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005730 if (finished)
5731 break;
5732 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005733 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005734 }
5735}
5736
5737// This gets run a separate thread to avoid stack blowout.
5738static void clang_annotateTokensImpl(void *UserData) {
5739 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5740 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5741 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5742 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5743 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5744
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005745 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005746 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5747 setThreadBackgroundPriority();
5748
5749 // Determine the region of interest, which contains all of the tokens.
5750 SourceRange RegionOfInterest;
5751 RegionOfInterest.setBegin(
5752 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5753 RegionOfInterest.setEnd(
5754 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5755 Tokens[NumTokens-1])));
5756
Guy Benyei11169dd2012-12-18 14:30:41 +00005757 // Relex the tokens within the source range to look for preprocessing
5758 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005759 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005760
5761 // If begin location points inside a macro argument, set it to the expansion
5762 // location so we can have the full context when annotating semantically.
5763 {
5764 SourceManager &SM = CXXUnit->getSourceManager();
5765 SourceLocation Loc =
5766 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5767 if (Loc.isMacroID())
5768 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5769 }
5770
Guy Benyei11169dd2012-12-18 14:30:41 +00005771 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5772 // Search and mark tokens that are macro argument expansions.
5773 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5774 Tokens, NumTokens);
5775 CursorVisitor MacroArgMarker(TU,
5776 MarkMacroArgTokensVisitorDelegate, &Visitor,
5777 /*VisitPreprocessorLast=*/true,
5778 /*VisitIncludedEntities=*/false,
5779 RegionOfInterest);
5780 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5781 }
5782
5783 // Annotate all of the source locations in the region of interest that map to
5784 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005785 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005786
5787 // FIXME: We use a ridiculous stack size here because the data-recursion
5788 // algorithm uses a large stack frame than the non-data recursive version,
5789 // and AnnotationTokensWorker currently transforms the data-recursion
5790 // algorithm back into a traditional recursion by explicitly calling
5791 // VisitChildren(). We will need to remove this explicit recursive call.
5792 W.AnnotateTokens();
5793
5794 // If we ran into any entities that involve context-sensitive keywords,
5795 // take another pass through the tokens to mark them as such.
5796 if (W.hasContextSensitiveKeywords()) {
5797 for (unsigned I = 0; I != NumTokens; ++I) {
5798 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5799 continue;
5800
5801 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5802 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005803 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005804 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5805 if (Property->getPropertyAttributesAsWritten() != 0 &&
5806 llvm::StringSwitch<bool>(II->getName())
5807 .Case("readonly", true)
5808 .Case("assign", true)
5809 .Case("unsafe_unretained", true)
5810 .Case("readwrite", true)
5811 .Case("retain", true)
5812 .Case("copy", true)
5813 .Case("nonatomic", true)
5814 .Case("atomic", true)
5815 .Case("getter", true)
5816 .Case("setter", true)
5817 .Case("strong", true)
5818 .Case("weak", true)
5819 .Default(false))
5820 Tokens[I].int_data[0] = CXToken_Keyword;
5821 }
5822 continue;
5823 }
5824
5825 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5826 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5827 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5828 if (llvm::StringSwitch<bool>(II->getName())
5829 .Case("in", true)
5830 .Case("out", true)
5831 .Case("inout", true)
5832 .Case("oneway", true)
5833 .Case("bycopy", true)
5834 .Case("byref", true)
5835 .Default(false))
5836 Tokens[I].int_data[0] = CXToken_Keyword;
5837 continue;
5838 }
5839
5840 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5841 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5842 Tokens[I].int_data[0] = CXToken_Keyword;
5843 continue;
5844 }
5845 }
5846 }
5847}
5848
5849extern "C" {
5850
5851void clang_annotateTokens(CXTranslationUnit TU,
5852 CXToken *Tokens, unsigned NumTokens,
5853 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005854 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005855 LOG_BAD_TU(TU);
5856 return;
5857 }
5858 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005859 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005860 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005861 }
5862
5863 LOG_FUNC_SECTION {
5864 *Log << TU << ' ';
5865 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5866 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5867 *Log << clang_getRange(bloc, eloc);
5868 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005869
5870 // Any token we don't specifically annotate will have a NULL cursor.
5871 CXCursor C = clang_getNullCursor();
5872 for (unsigned I = 0; I != NumTokens; ++I)
5873 Cursors[I] = C;
5874
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005875 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005876 if (!CXXUnit)
5877 return;
5878
5879 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5880
5881 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5882 llvm::CrashRecoveryContext CRC;
5883 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5884 GetSafetyThreadStackSize() * 2)) {
5885 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5886 }
5887}
5888
5889} // end: extern "C"
5890
5891//===----------------------------------------------------------------------===//
5892// Operations for querying linkage of a cursor.
5893//===----------------------------------------------------------------------===//
5894
5895extern "C" {
5896CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5897 if (!clang_isDeclaration(cursor.kind))
5898 return CXLinkage_Invalid;
5899
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005900 const Decl *D = cxcursor::getCursorDecl(cursor);
5901 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005902 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005903 case NoLinkage:
5904 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005905 case InternalLinkage: return CXLinkage_Internal;
5906 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5907 case ExternalLinkage: return CXLinkage_External;
5908 };
5909
5910 return CXLinkage_Invalid;
5911}
5912} // end: extern "C"
5913
5914//===----------------------------------------------------------------------===//
5915// Operations for querying language of a cursor.
5916//===----------------------------------------------------------------------===//
5917
5918static CXLanguageKind getDeclLanguage(const Decl *D) {
5919 if (!D)
5920 return CXLanguage_C;
5921
5922 switch (D->getKind()) {
5923 default:
5924 break;
5925 case Decl::ImplicitParam:
5926 case Decl::ObjCAtDefsField:
5927 case Decl::ObjCCategory:
5928 case Decl::ObjCCategoryImpl:
5929 case Decl::ObjCCompatibleAlias:
5930 case Decl::ObjCImplementation:
5931 case Decl::ObjCInterface:
5932 case Decl::ObjCIvar:
5933 case Decl::ObjCMethod:
5934 case Decl::ObjCProperty:
5935 case Decl::ObjCPropertyImpl:
5936 case Decl::ObjCProtocol:
5937 return CXLanguage_ObjC;
5938 case Decl::CXXConstructor:
5939 case Decl::CXXConversion:
5940 case Decl::CXXDestructor:
5941 case Decl::CXXMethod:
5942 case Decl::CXXRecord:
5943 case Decl::ClassTemplate:
5944 case Decl::ClassTemplatePartialSpecialization:
5945 case Decl::ClassTemplateSpecialization:
5946 case Decl::Friend:
5947 case Decl::FriendTemplate:
5948 case Decl::FunctionTemplate:
5949 case Decl::LinkageSpec:
5950 case Decl::Namespace:
5951 case Decl::NamespaceAlias:
5952 case Decl::NonTypeTemplateParm:
5953 case Decl::StaticAssert:
5954 case Decl::TemplateTemplateParm:
5955 case Decl::TemplateTypeParm:
5956 case Decl::UnresolvedUsingTypename:
5957 case Decl::UnresolvedUsingValue:
5958 case Decl::Using:
5959 case Decl::UsingDirective:
5960 case Decl::UsingShadow:
5961 return CXLanguage_CPlusPlus;
5962 }
5963
5964 return CXLanguage_C;
5965}
5966
5967extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005968
5969static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5970 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5971 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005972
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005973 switch (D->getAvailability()) {
5974 case AR_Available:
5975 case AR_NotYetIntroduced:
5976 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005977 return getCursorAvailabilityForDecl(
5978 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005979 return CXAvailability_Available;
5980
5981 case AR_Deprecated:
5982 return CXAvailability_Deprecated;
5983
5984 case AR_Unavailable:
5985 return CXAvailability_NotAvailable;
5986 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005987
5988 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005989}
5990
Guy Benyei11169dd2012-12-18 14:30:41 +00005991enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5992 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005993 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5994 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005995
5996 return CXAvailability_Available;
5997}
5998
5999static CXVersion convertVersion(VersionTuple In) {
6000 CXVersion Out = { -1, -1, -1 };
6001 if (In.empty())
6002 return Out;
6003
6004 Out.Major = In.getMajor();
6005
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006006 Optional<unsigned> Minor = In.getMinor();
6007 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006008 Out.Minor = *Minor;
6009 else
6010 return Out;
6011
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006012 Optional<unsigned> Subminor = In.getSubminor();
6013 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006014 Out.Subminor = *Subminor;
6015
6016 return Out;
6017}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006018
6019static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6020 int *always_deprecated,
6021 CXString *deprecated_message,
6022 int *always_unavailable,
6023 CXString *unavailable_message,
6024 CXPlatformAvailability *availability,
6025 int availability_size) {
6026 bool HadAvailAttr = false;
6027 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006028 for (auto A : D->attrs()) {
6029 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006030 HadAvailAttr = true;
6031 if (always_deprecated)
6032 *always_deprecated = 1;
6033 if (deprecated_message)
6034 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
6035 continue;
6036 }
6037
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006038 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006039 HadAvailAttr = true;
6040 if (always_unavailable)
6041 *always_unavailable = 1;
6042 if (unavailable_message) {
6043 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6044 }
6045 continue;
6046 }
6047
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006048 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006049 HadAvailAttr = true;
6050 if (N < availability_size) {
6051 availability[N].Platform
6052 = cxstring::createDup(Avail->getPlatform()->getName());
6053 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6054 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6055 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6056 availability[N].Unavailable = Avail->getUnavailable();
6057 availability[N].Message = cxstring::createDup(Avail->getMessage());
6058 }
6059 ++N;
6060 }
6061 }
6062
6063 if (!HadAvailAttr)
6064 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6065 return getCursorPlatformAvailabilityForDecl(
6066 cast<Decl>(EnumConst->getDeclContext()),
6067 always_deprecated,
6068 deprecated_message,
6069 always_unavailable,
6070 unavailable_message,
6071 availability,
6072 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006073
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006074 return N;
6075}
6076
Guy Benyei11169dd2012-12-18 14:30:41 +00006077int clang_getCursorPlatformAvailability(CXCursor cursor,
6078 int *always_deprecated,
6079 CXString *deprecated_message,
6080 int *always_unavailable,
6081 CXString *unavailable_message,
6082 CXPlatformAvailability *availability,
6083 int availability_size) {
6084 if (always_deprecated)
6085 *always_deprecated = 0;
6086 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006087 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006088 if (always_unavailable)
6089 *always_unavailable = 0;
6090 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006091 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006092
Guy Benyei11169dd2012-12-18 14:30:41 +00006093 if (!clang_isDeclaration(cursor.kind))
6094 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006095
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006096 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006097 if (!D)
6098 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006099
6100 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6101 deprecated_message,
6102 always_unavailable,
6103 unavailable_message,
6104 availability,
6105 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006106}
6107
6108void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6109 clang_disposeString(availability->Platform);
6110 clang_disposeString(availability->Message);
6111}
6112
6113CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6114 if (clang_isDeclaration(cursor.kind))
6115 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6116
6117 return CXLanguage_Invalid;
6118}
6119
6120 /// \brief If the given cursor is the "templated" declaration
6121 /// descibing a class or function template, return the class or
6122 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006123static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006124 if (!D)
6125 return 0;
6126
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006127 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006128 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6129 return FunTmpl;
6130
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006131 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006132 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6133 return ClassTmpl;
6134
6135 return D;
6136}
6137
6138CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6139 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006140 if (const Decl *D = getCursorDecl(cursor)) {
6141 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006142 if (!DC)
6143 return clang_getNullCursor();
6144
6145 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6146 getCursorTU(cursor));
6147 }
6148 }
6149
6150 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006151 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006152 return MakeCXCursor(D, getCursorTU(cursor));
6153 }
6154
6155 return clang_getNullCursor();
6156}
6157
6158CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6159 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006160 if (const Decl *D = getCursorDecl(cursor)) {
6161 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006162 if (!DC)
6163 return clang_getNullCursor();
6164
6165 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6166 getCursorTU(cursor));
6167 }
6168 }
6169
6170 // FIXME: Note that we can't easily compute the lexical context of a
6171 // statement or expression, so we return nothing.
6172 return clang_getNullCursor();
6173}
6174
6175CXFile clang_getIncludedFile(CXCursor cursor) {
6176 if (cursor.kind != CXCursor_InclusionDirective)
6177 return 0;
6178
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006179 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006180 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006181}
6182
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006183unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6184 if (C.kind != CXCursor_ObjCPropertyDecl)
6185 return CXObjCPropertyAttr_noattr;
6186
6187 unsigned Result = CXObjCPropertyAttr_noattr;
6188 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6189 ObjCPropertyDecl::PropertyAttributeKind Attr =
6190 PD->getPropertyAttributesAsWritten();
6191
6192#define SET_CXOBJCPROP_ATTR(A) \
6193 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6194 Result |= CXObjCPropertyAttr_##A
6195 SET_CXOBJCPROP_ATTR(readonly);
6196 SET_CXOBJCPROP_ATTR(getter);
6197 SET_CXOBJCPROP_ATTR(assign);
6198 SET_CXOBJCPROP_ATTR(readwrite);
6199 SET_CXOBJCPROP_ATTR(retain);
6200 SET_CXOBJCPROP_ATTR(copy);
6201 SET_CXOBJCPROP_ATTR(nonatomic);
6202 SET_CXOBJCPROP_ATTR(setter);
6203 SET_CXOBJCPROP_ATTR(atomic);
6204 SET_CXOBJCPROP_ATTR(weak);
6205 SET_CXOBJCPROP_ATTR(strong);
6206 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6207#undef SET_CXOBJCPROP_ATTR
6208
6209 return Result;
6210}
6211
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006212unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6213 if (!clang_isDeclaration(C.kind))
6214 return CXObjCDeclQualifier_None;
6215
6216 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6217 const Decl *D = getCursorDecl(C);
6218 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6219 QT = MD->getObjCDeclQualifier();
6220 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6221 QT = PD->getObjCDeclQualifier();
6222 if (QT == Decl::OBJC_TQ_None)
6223 return CXObjCDeclQualifier_None;
6224
6225 unsigned Result = CXObjCDeclQualifier_None;
6226 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6227 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6228 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6229 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6230 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6231 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6232
6233 return Result;
6234}
6235
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006236unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6237 if (!clang_isDeclaration(C.kind))
6238 return 0;
6239
6240 const Decl *D = getCursorDecl(C);
6241 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6242 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6243 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6244 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6245
6246 return 0;
6247}
6248
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006249unsigned clang_Cursor_isVariadic(CXCursor C) {
6250 if (!clang_isDeclaration(C.kind))
6251 return 0;
6252
6253 const Decl *D = getCursorDecl(C);
6254 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6255 return FD->isVariadic();
6256 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6257 return MD->isVariadic();
6258
6259 return 0;
6260}
6261
Guy Benyei11169dd2012-12-18 14:30:41 +00006262CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6263 if (!clang_isDeclaration(C.kind))
6264 return clang_getNullRange();
6265
6266 const Decl *D = getCursorDecl(C);
6267 ASTContext &Context = getCursorContext(C);
6268 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6269 if (!RC)
6270 return clang_getNullRange();
6271
6272 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6273}
6274
6275CXString clang_Cursor_getRawCommentText(CXCursor C) {
6276 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006277 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006278
6279 const Decl *D = getCursorDecl(C);
6280 ASTContext &Context = getCursorContext(C);
6281 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6282 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6283 StringRef();
6284
6285 // Don't duplicate the string because RawText points directly into source
6286 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006287 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006288}
6289
6290CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6291 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006292 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006293
6294 const Decl *D = getCursorDecl(C);
6295 const ASTContext &Context = getCursorContext(C);
6296 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6297
6298 if (RC) {
6299 StringRef BriefText = RC->getBriefText(Context);
6300
6301 // Don't duplicate the string because RawComment ensures that this memory
6302 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006303 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006304 }
6305
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006306 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006307}
6308
6309CXComment clang_Cursor_getParsedComment(CXCursor C) {
6310 if (!clang_isDeclaration(C.kind))
6311 return cxcomment::createCXComment(NULL, NULL);
6312
6313 const Decl *D = getCursorDecl(C);
6314 const ASTContext &Context = getCursorContext(C);
6315 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6316
6317 return cxcomment::createCXComment(FC, getCursorTU(C));
6318}
6319
6320CXModule clang_Cursor_getModule(CXCursor C) {
6321 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006322 if (const ImportDecl *ImportD =
6323 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006324 return ImportD->getImportedModule();
6325 }
6326
6327 return 0;
6328}
6329
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006330CXFile clang_Module_getASTFile(CXModule CXMod) {
6331 if (!CXMod)
6332 return 0;
6333 Module *Mod = static_cast<Module*>(CXMod);
6334 return const_cast<FileEntry *>(Mod->getASTFile());
6335}
6336
Guy Benyei11169dd2012-12-18 14:30:41 +00006337CXModule clang_Module_getParent(CXModule CXMod) {
6338 if (!CXMod)
6339 return 0;
6340 Module *Mod = static_cast<Module*>(CXMod);
6341 return Mod->Parent;
6342}
6343
6344CXString clang_Module_getName(CXModule CXMod) {
6345 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006346 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006347 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006348 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006349}
6350
6351CXString clang_Module_getFullName(CXModule CXMod) {
6352 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006353 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006354 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006355 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006356}
6357
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006358unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6359 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006360 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006361 LOG_BAD_TU(TU);
6362 return 0;
6363 }
6364 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006365 return 0;
6366 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006367 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6368 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6369 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006370}
6371
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006372CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6373 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006374 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006375 LOG_BAD_TU(TU);
6376 return 0;
6377 }
6378 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006379 return 0;
6380 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006381 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006382
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006383 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6384 if (Index < TopHeaders.size())
6385 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006386
6387 return 0;
6388}
6389
6390} // end: extern "C"
6391
6392//===----------------------------------------------------------------------===//
6393// C++ AST instrospection.
6394//===----------------------------------------------------------------------===//
6395
6396extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006397unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6398 if (!clang_isDeclaration(C.kind))
6399 return 0;
6400
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006401 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006402 const CXXMethodDecl *Method =
6403 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006404 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6405}
6406
Guy Benyei11169dd2012-12-18 14:30:41 +00006407unsigned clang_CXXMethod_isStatic(CXCursor C) {
6408 if (!clang_isDeclaration(C.kind))
6409 return 0;
6410
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006411 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006412 const CXXMethodDecl *Method =
6413 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006414 return (Method && Method->isStatic()) ? 1 : 0;
6415}
6416
6417unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6418 if (!clang_isDeclaration(C.kind))
6419 return 0;
6420
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006421 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006422 const CXXMethodDecl *Method =
6423 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006424 return (Method && Method->isVirtual()) ? 1 : 0;
6425}
6426} // end: extern "C"
6427
6428//===----------------------------------------------------------------------===//
6429// Attribute introspection.
6430//===----------------------------------------------------------------------===//
6431
6432extern "C" {
6433CXType clang_getIBOutletCollectionType(CXCursor C) {
6434 if (C.kind != CXCursor_IBOutletCollectionAttr)
6435 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6436
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006437 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006438 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6439
6440 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6441}
6442} // end: extern "C"
6443
6444//===----------------------------------------------------------------------===//
6445// Inspecting memory usage.
6446//===----------------------------------------------------------------------===//
6447
6448typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6449
6450static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6451 enum CXTUResourceUsageKind k,
6452 unsigned long amount) {
6453 CXTUResourceUsageEntry entry = { k, amount };
6454 entries.push_back(entry);
6455}
6456
6457extern "C" {
6458
6459const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6460 const char *str = "";
6461 switch (kind) {
6462 case CXTUResourceUsage_AST:
6463 str = "ASTContext: expressions, declarations, and types";
6464 break;
6465 case CXTUResourceUsage_Identifiers:
6466 str = "ASTContext: identifiers";
6467 break;
6468 case CXTUResourceUsage_Selectors:
6469 str = "ASTContext: selectors";
6470 break;
6471 case CXTUResourceUsage_GlobalCompletionResults:
6472 str = "Code completion: cached global results";
6473 break;
6474 case CXTUResourceUsage_SourceManagerContentCache:
6475 str = "SourceManager: content cache allocator";
6476 break;
6477 case CXTUResourceUsage_AST_SideTables:
6478 str = "ASTContext: side tables";
6479 break;
6480 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6481 str = "SourceManager: malloc'ed memory buffers";
6482 break;
6483 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6484 str = "SourceManager: mmap'ed memory buffers";
6485 break;
6486 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6487 str = "ExternalASTSource: malloc'ed memory buffers";
6488 break;
6489 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6490 str = "ExternalASTSource: mmap'ed memory buffers";
6491 break;
6492 case CXTUResourceUsage_Preprocessor:
6493 str = "Preprocessor: malloc'ed memory";
6494 break;
6495 case CXTUResourceUsage_PreprocessingRecord:
6496 str = "Preprocessor: PreprocessingRecord";
6497 break;
6498 case CXTUResourceUsage_SourceManager_DataStructures:
6499 str = "SourceManager: data structures and tables";
6500 break;
6501 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6502 str = "Preprocessor: header search tables";
6503 break;
6504 }
6505 return str;
6506}
6507
6508CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006509 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006510 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006511 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6512 return usage;
6513 }
6514
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006515 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006516 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006517 ASTContext &astContext = astUnit->getASTContext();
6518
6519 // How much memory is used by AST nodes and types?
6520 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6521 (unsigned long) astContext.getASTAllocatedMemory());
6522
6523 // How much memory is used by identifiers?
6524 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6525 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6526
6527 // How much memory is used for selectors?
6528 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6529 (unsigned long) astContext.Selectors.getTotalMemory());
6530
6531 // How much memory is used by ASTContext's side tables?
6532 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6533 (unsigned long) astContext.getSideTableAllocatedMemory());
6534
6535 // How much memory is used for caching global code completion results?
6536 unsigned long completionBytes = 0;
6537 if (GlobalCodeCompletionAllocator *completionAllocator =
6538 astUnit->getCachedCompletionAllocator().getPtr()) {
6539 completionBytes = completionAllocator->getTotalMemory();
6540 }
6541 createCXTUResourceUsageEntry(*entries,
6542 CXTUResourceUsage_GlobalCompletionResults,
6543 completionBytes);
6544
6545 // How much memory is being used by SourceManager's content cache?
6546 createCXTUResourceUsageEntry(*entries,
6547 CXTUResourceUsage_SourceManagerContentCache,
6548 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6549
6550 // How much memory is being used by the MemoryBuffer's in SourceManager?
6551 const SourceManager::MemoryBufferSizes &srcBufs =
6552 astUnit->getSourceManager().getMemoryBufferSizes();
6553
6554 createCXTUResourceUsageEntry(*entries,
6555 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6556 (unsigned long) srcBufs.malloc_bytes);
6557 createCXTUResourceUsageEntry(*entries,
6558 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6559 (unsigned long) srcBufs.mmap_bytes);
6560 createCXTUResourceUsageEntry(*entries,
6561 CXTUResourceUsage_SourceManager_DataStructures,
6562 (unsigned long) astContext.getSourceManager()
6563 .getDataStructureSizes());
6564
6565 // How much memory is being used by the ExternalASTSource?
6566 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6567 const ExternalASTSource::MemoryBufferSizes &sizes =
6568 esrc->getMemoryBufferSizes();
6569
6570 createCXTUResourceUsageEntry(*entries,
6571 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6572 (unsigned long) sizes.malloc_bytes);
6573 createCXTUResourceUsageEntry(*entries,
6574 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6575 (unsigned long) sizes.mmap_bytes);
6576 }
6577
6578 // How much memory is being used by the Preprocessor?
6579 Preprocessor &pp = astUnit->getPreprocessor();
6580 createCXTUResourceUsageEntry(*entries,
6581 CXTUResourceUsage_Preprocessor,
6582 pp.getTotalMemory());
6583
6584 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6585 createCXTUResourceUsageEntry(*entries,
6586 CXTUResourceUsage_PreprocessingRecord,
6587 pRec->getTotalMemory());
6588 }
6589
6590 createCXTUResourceUsageEntry(*entries,
6591 CXTUResourceUsage_Preprocessor_HeaderSearch,
6592 pp.getHeaderSearchInfo().getTotalMemory());
6593
6594 CXTUResourceUsage usage = { (void*) entries.get(),
6595 (unsigned) entries->size(),
6596 entries->size() ? &(*entries)[0] : 0 };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006597 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006598 return usage;
6599}
6600
6601void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6602 if (usage.data)
6603 delete (MemUsageEntries*) usage.data;
6604}
6605
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006606CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6607 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006608 skipped->count = 0;
6609 skipped->ranges = 0;
6610
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006611 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006612 LOG_BAD_TU(TU);
6613 return skipped;
6614 }
6615
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006616 if (!file)
6617 return skipped;
6618
6619 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6620 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6621 if (!ppRec)
6622 return skipped;
6623
6624 ASTContext &Ctx = astUnit->getASTContext();
6625 SourceManager &sm = Ctx.getSourceManager();
6626 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6627 FileID wantedFileID = sm.translateFile(fileEntry);
6628
6629 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6630 std::vector<SourceRange> wantedRanges;
6631 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6632 i != ei; ++i) {
6633 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6634 wantedRanges.push_back(*i);
6635 }
6636
6637 skipped->count = wantedRanges.size();
6638 skipped->ranges = new CXSourceRange[skipped->count];
6639 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6640 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6641
6642 return skipped;
6643}
6644
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006645void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6646 if (ranges) {
6647 delete[] ranges->ranges;
6648 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006649 }
6650}
6651
Guy Benyei11169dd2012-12-18 14:30:41 +00006652} // end extern "C"
6653
6654void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6655 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6656 for (unsigned I = 0; I != Usage.numEntries; ++I)
6657 fprintf(stderr, " %s: %lu\n",
6658 clang_getTUResourceUsageName(Usage.entries[I].kind),
6659 Usage.entries[I].amount);
6660
6661 clang_disposeCXTUResourceUsage(Usage);
6662}
6663
6664//===----------------------------------------------------------------------===//
6665// Misc. utility functions.
6666//===----------------------------------------------------------------------===//
6667
6668/// Default to using an 8 MB stack size on "safety" threads.
6669static unsigned SafetyStackThreadSize = 8 << 20;
6670
6671namespace clang {
6672
6673bool RunSafely(llvm::CrashRecoveryContext &CRC,
6674 void (*Fn)(void*), void *UserData,
6675 unsigned Size) {
6676 if (!Size)
6677 Size = GetSafetyThreadStackSize();
6678 if (Size)
6679 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6680 return CRC.RunSafely(Fn, UserData);
6681}
6682
6683unsigned GetSafetyThreadStackSize() {
6684 return SafetyStackThreadSize;
6685}
6686
6687void SetSafetyThreadStackSize(unsigned Value) {
6688 SafetyStackThreadSize = Value;
6689}
6690
6691}
6692
6693void clang::setThreadBackgroundPriority() {
6694 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6695 return;
6696
6697 // FIXME: Move to llvm/Support and make it cross-platform.
6698#ifdef __APPLE__
6699 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6700#endif
6701}
6702
6703void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6704 if (!Unit)
6705 return;
6706
6707 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6708 DEnd = Unit->stored_diag_end();
6709 D != DEnd; ++D) {
6710 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6711 CXString Msg = clang_formatDiagnostic(&Diag,
6712 clang_defaultDiagnosticDisplayOptions());
6713 fprintf(stderr, "%s\n", clang_getCString(Msg));
6714 clang_disposeString(Msg);
6715 }
6716#ifdef LLVM_ON_WIN32
6717 // On Windows, force a flush, since there may be multiple copies of
6718 // stderr and stdout in the file system, all with different buffers
6719 // but writing to the same device.
6720 fflush(stderr);
6721#endif
6722}
6723
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006724MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6725 SourceLocation MacroDefLoc,
6726 CXTranslationUnit TU){
6727 if (MacroDefLoc.isInvalid() || !TU)
6728 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006729 if (!II.hadMacroDefinition())
6730 return 0;
6731
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006732 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006733 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006734 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006735 if (MD) {
6736 for (MacroDirective::DefInfo
6737 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6738 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6739 return Def.getMacroInfo();
6740 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006741 }
6742
6743 return 0;
6744}
6745
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006746const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6747 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006748 if (!MacroDef || !TU)
6749 return 0;
6750 const IdentifierInfo *II = MacroDef->getName();
6751 if (!II)
6752 return 0;
6753
6754 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6755}
6756
6757MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6758 const Token &Tok,
6759 CXTranslationUnit TU) {
6760 if (!MI || !TU)
6761 return 0;
6762 if (Tok.isNot(tok::raw_identifier))
6763 return 0;
6764
6765 if (MI->getNumTokens() == 0)
6766 return 0;
6767 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6768 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006769 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006770
6771 // Check that the token is inside the definition and not its argument list.
6772 SourceManager &SM = Unit->getSourceManager();
6773 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6774 return 0;
6775 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6776 return 0;
6777
6778 Preprocessor &PP = Unit->getPreprocessor();
6779 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6780 if (!PPRec)
6781 return 0;
6782
6783 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6784 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6785 if (!II.hadMacroDefinition())
6786 return 0;
6787
6788 // Check that the identifier is not one of the macro arguments.
6789 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6790 return 0;
6791
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006792 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6793 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006794 return 0;
6795
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006796 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006797}
6798
6799MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6800 SourceLocation Loc,
6801 CXTranslationUnit TU) {
6802 if (Loc.isInvalid() || !MI || !TU)
6803 return 0;
6804
6805 if (MI->getNumTokens() == 0)
6806 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006807 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006808 Preprocessor &PP = Unit->getPreprocessor();
6809 if (!PP.getPreprocessingRecord())
6810 return 0;
6811 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6812 Token Tok;
6813 if (PP.getRawToken(Loc, Tok))
6814 return 0;
6815
6816 return checkForMacroInMacroDefinition(MI, Tok, TU);
6817}
6818
Guy Benyei11169dd2012-12-18 14:30:41 +00006819extern "C" {
6820
6821CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006822 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006823}
6824
6825} // end: extern "C"
6826
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006827Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6828 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006829 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006830 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006831 if (Unit->isMainFileAST())
6832 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006833 return *this;
6834 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006835 } else {
6836 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006837 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006838 return *this;
6839}
6840
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006841Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6842 *this << FE->getName();
6843 return *this;
6844}
6845
6846Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6847 CXString cursorName = clang_getCursorDisplayName(cursor);
6848 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6849 clang_disposeString(cursorName);
6850 return *this;
6851}
6852
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006853Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6854 CXFile File;
6855 unsigned Line, Column;
6856 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6857 CXString FileName = clang_getFileName(File);
6858 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6859 clang_disposeString(FileName);
6860 return *this;
6861}
6862
6863Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6864 CXSourceLocation BLoc = clang_getRangeStart(range);
6865 CXSourceLocation ELoc = clang_getRangeEnd(range);
6866
6867 CXFile BFile;
6868 unsigned BLine, BColumn;
6869 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6870
6871 CXFile EFile;
6872 unsigned ELine, EColumn;
6873 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6874
6875 CXString BFileName = clang_getFileName(BFile);
6876 if (BFile == EFile) {
6877 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6878 BLine, BColumn, ELine, EColumn);
6879 } else {
6880 CXString EFileName = clang_getFileName(EFile);
6881 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6882 BLine, BColumn)
6883 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6884 ELine, EColumn);
6885 clang_disposeString(EFileName);
6886 }
6887 clang_disposeString(BFileName);
6888 return *this;
6889}
6890
6891Logger &cxindex::Logger::operator<<(CXString Str) {
6892 *this << clang_getCString(Str);
6893 return *this;
6894}
6895
6896Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6897 LogOS << Fmt;
6898 return *this;
6899}
6900
6901cxindex::Logger::~Logger() {
6902 LogOS.flush();
6903
6904 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6905
6906 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6907
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006908 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006909 OS << "[libclang:" << Name << ':';
6910
6911 // FIXME: Portability.
6912#if HAVE_PTHREAD_H && __APPLE__
6913 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6914 OS << tid << ':';
6915#endif
6916
6917 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6918 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6919 OS << Msg.str() << '\n';
6920
6921 if (Trace) {
6922 llvm::sys::PrintStackTrace(stderr);
6923 OS << "--------------------------------------------------\n";
6924 }
6925}