blob: 50e7c682048ae22398cdf2dcf4c9b5b0188022ad [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXComment.h"
19#include "CXCursor.h"
20#include "CXSourceLocation.h"
21#include "CXString.h"
22#include "CXTranslationUnit.h"
23#include "CXType.h"
24#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000025#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000030#include "clang/Basic/Version.h"
31#include "clang/Frontend/ASTUnit.h"
32#include "clang/Frontend/CompilerInstance.h"
33#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000034#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000035#include "clang/Lex/HeaderSearch.h"
36#include "clang/Lex/Lexer.h"
37#include "clang/Lex/PreprocessingRecord.h"
38#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000039#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000040#include "llvm/ADT/Optional.h"
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/StringSwitch.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000043#include "llvm/Config/config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000044#include "llvm/Support/Compiler.h"
45#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000046#include "llvm/Support/Format.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/MemoryBuffer.h"
48#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000049#include "llvm/Support/Program.h"
50#include "llvm/Support/SaveAndRestore.h"
51#include "llvm/Support/Signals.h"
52#include "llvm/Support/Threading.h"
53#include "llvm/Support/Timer.h"
54#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000055
56#if HAVE_PTHREAD_H
57#include <pthread.h>
58#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000059
60using namespace clang;
61using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000062using namespace clang::cxtu;
63using namespace clang::cxindex;
64
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000065CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
66 if (!AU)
Guy Benyei11169dd2012-12-18 14:30:41 +000067 return 0;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000068 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000069 CXTranslationUnit D = new CXTranslationUnitImpl();
70 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000071 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000072 D->StringPool = new cxstring::CXStringPool();
Guy Benyei11169dd2012-12-18 14:30:41 +000073 D->Diagnostics = 0;
74 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Dmitri Gribenko9e605112013-11-13 22:16:51 +000075 D->CommentToXML = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +000076 return D;
77}
78
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000079bool cxtu::isASTReadError(ASTUnit *AU) {
80 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
81 DEnd = AU->stored_diag_end();
82 D != DEnd; ++D) {
83 if (D->getLevel() >= DiagnosticsEngine::Error &&
84 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
85 diag::DiagCat_AST_Deserialization_Issue)
86 return true;
87 }
88 return false;
89}
90
Guy Benyei11169dd2012-12-18 14:30:41 +000091cxtu::CXTUOwner::~CXTUOwner() {
92 if (TU)
93 clang_disposeTranslationUnit(TU);
94}
95
96/// \brief Compare two source ranges to determine their relative position in
97/// the translation unit.
98static RangeComparisonResult RangeCompare(SourceManager &SM,
99 SourceRange R1,
100 SourceRange R2) {
101 assert(R1.isValid() && "First range is invalid?");
102 assert(R2.isValid() && "Second range is invalid?");
103 if (R1.getEnd() != R2.getBegin() &&
104 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
105 return RangeBefore;
106 if (R2.getEnd() != R1.getBegin() &&
107 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
108 return RangeAfter;
109 return RangeOverlap;
110}
111
112/// \brief Determine if a source location falls within, before, or after a
113/// a given source range.
114static RangeComparisonResult LocationCompare(SourceManager &SM,
115 SourceLocation L, SourceRange R) {
116 assert(R.isValid() && "First range is invalid?");
117 assert(L.isValid() && "Second range is invalid?");
118 if (L == R.getBegin() || L == R.getEnd())
119 return RangeOverlap;
120 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
121 return RangeBefore;
122 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
123 return RangeAfter;
124 return RangeOverlap;
125}
126
127/// \brief Translate a Clang source range into a CIndex source range.
128///
129/// Clang internally represents ranges where the end location points to the
130/// start of the token at the end. However, for external clients it is more
131/// useful to have a CXSourceRange be a proper half-open interval. This routine
132/// does the appropriate translation.
133CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
134 const LangOptions &LangOpts,
135 const CharSourceRange &R) {
136 // We want the last character in this location, so we will adjust the
137 // location accordingly.
138 SourceLocation EndLoc = R.getEnd();
139 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
140 EndLoc = SM.getExpansionRange(EndLoc).second;
141 if (R.isTokenRange() && !EndLoc.isInvalid()) {
142 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
143 SM, LangOpts);
144 EndLoc = EndLoc.getLocWithOffset(Length);
145 }
146
Bill Wendlingeade3622013-01-23 08:25:41 +0000147 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000148 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000149 R.getBegin().getRawEncoding(),
150 EndLoc.getRawEncoding()
151 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000152 return Result;
153}
154
155//===----------------------------------------------------------------------===//
156// Cursor visitor.
157//===----------------------------------------------------------------------===//
158
159static SourceRange getRawCursorExtent(CXCursor C);
160static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
161
162
163RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
164 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
165}
166
167/// \brief Visit the given cursor and, if requested by the visitor,
168/// its children.
169///
170/// \param Cursor the cursor to visit.
171///
172/// \param CheckedRegionOfInterest if true, then the caller already checked
173/// that this cursor is within the region of interest.
174///
175/// \returns true if the visitation should be aborted, false if it
176/// should continue.
177bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
178 if (clang_isInvalid(Cursor.kind))
179 return false;
180
181 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000182 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000183 if (!D) {
184 assert(0 && "Invalid declaration cursor");
185 return true; // abort.
186 }
187
188 // Ignore implicit declarations, unless it's an objc method because
189 // currently we should report implicit methods for properties when indexing.
190 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
191 return false;
192 }
193
194 // If we have a range of interest, and this cursor doesn't intersect with it,
195 // we're done.
196 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
197 SourceRange Range = getRawCursorExtent(Cursor);
198 if (Range.isInvalid() || CompareRegionOfInterest(Range))
199 return false;
200 }
201
202 switch (Visitor(Cursor, Parent, ClientData)) {
203 case CXChildVisit_Break:
204 return true;
205
206 case CXChildVisit_Continue:
207 return false;
208
209 case CXChildVisit_Recurse: {
210 bool ret = VisitChildren(Cursor);
211 if (PostChildrenVisitor)
212 if (PostChildrenVisitor(Cursor, ClientData))
213 return true;
214 return ret;
215 }
216 }
217
218 llvm_unreachable("Invalid CXChildVisitResult!");
219}
220
221static bool visitPreprocessedEntitiesInRange(SourceRange R,
222 PreprocessingRecord &PPRec,
223 CursorVisitor &Visitor) {
224 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
225 FileID FID;
226
227 if (!Visitor.shouldVisitIncludedEntities()) {
228 // If the begin/end of the range lie in the same FileID, do the optimization
229 // where we skip preprocessed entities that do not come from the same FileID.
230 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
231 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
232 FID = FileID();
233 }
234
235 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
236 Entities = PPRec.getPreprocessedEntitiesInRange(R);
237 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
238 PPRec, FID);
239}
240
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000241bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000242 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000243 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000244
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000245 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 SourceManager &SM = Unit->getSourceManager();
247
248 std::pair<FileID, unsigned>
249 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
250 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
251
252 if (End.first != Begin.first) {
253 // If the end does not reside in the same file, try to recover by
254 // picking the end of the file of begin location.
255 End.first = Begin.first;
256 End.second = SM.getFileIDSize(Begin.first);
257 }
258
259 assert(Begin.first == End.first);
260 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000261 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000262
263 FileID File = Begin.first;
264 unsigned Offset = Begin.second;
265 unsigned Length = End.second - Begin.second;
266
267 if (!VisitDeclsOnly && !VisitPreprocessorLast)
268 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000271 if (visitDeclsFromFileRegion(File, Offset, Length))
272 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000273
274 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000275 return visitPreprocessedEntitiesInRegion();
276
277 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000278}
279
280static bool isInLexicalContext(Decl *D, DeclContext *DC) {
281 if (!DC)
282 return false;
283
284 for (DeclContext *DeclDC = D->getLexicalDeclContext();
285 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
286 if (DeclDC == DC)
287 return true;
288 }
289 return false;
290}
291
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000292bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000293 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000294 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000295 SourceManager &SM = Unit->getSourceManager();
296 SourceRange Range = RegionOfInterest;
297
298 SmallVector<Decl *, 16> Decls;
299 Unit->findFileRegionDecls(File, Offset, Length, Decls);
300
301 // If we didn't find any file level decls for the file, try looking at the
302 // file that it was included from.
303 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
304 bool Invalid = false;
305 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
306 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000307 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000308
309 SourceLocation Outer;
310 if (SLEntry.isFile())
311 Outer = SLEntry.getFile().getIncludeLoc();
312 else
313 Outer = SLEntry.getExpansion().getExpansionLocStart();
314 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000317 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000318 Length = 0;
319 Unit->findFileRegionDecls(File, Offset, Length, Decls);
320 }
321
322 assert(!Decls.empty());
323
324 bool VisitedAtLeastOnce = false;
325 DeclContext *CurDC = 0;
Craig Topper2341c0d2013-07-04 03:08:24 +0000326 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
327 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000328 Decl *D = *DIt;
329 if (D->getSourceRange().isInvalid())
330 continue;
331
332 if (isInLexicalContext(D, CurDC))
333 continue;
334
335 CurDC = dyn_cast<DeclContext>(D);
336
337 if (TagDecl *TD = dyn_cast<TagDecl>(D))
338 if (!TD->isFreeStanding())
339 continue;
340
341 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
342 if (CompRes == RangeBefore)
343 continue;
344 if (CompRes == RangeAfter)
345 break;
346
347 assert(CompRes == RangeOverlap);
348 VisitedAtLeastOnce = true;
349
350 if (isa<ObjCContainerDecl>(D)) {
351 FileDI_current = &DIt;
352 FileDE_current = DE;
353 } else {
354 FileDI_current = 0;
355 }
356
357 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000358 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000359 }
360
361 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000362 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363
364 // No Decls overlapped with the range. Move up the lexical context until there
365 // is a context that contains the range or we reach the translation unit
366 // level.
367 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
368 : (*(DIt-1))->getLexicalDeclContext();
369
370 while (DC && !DC->isTranslationUnit()) {
371 Decl *D = cast<Decl>(DC);
372 SourceRange CurDeclRange = D->getSourceRange();
373 if (CurDeclRange.isInvalid())
374 break;
375
376 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000377 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
378 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000379 }
380
381 DC = D->getLexicalDeclContext();
382 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000383
384 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000385}
386
387bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
388 if (!AU->getPreprocessor().getPreprocessingRecord())
389 return false;
390
391 PreprocessingRecord &PPRec
392 = *AU->getPreprocessor().getPreprocessingRecord();
393 SourceManager &SM = AU->getSourceManager();
394
395 if (RegionOfInterest.isValid()) {
396 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
397 SourceLocation B = MappedRange.getBegin();
398 SourceLocation E = MappedRange.getEnd();
399
400 if (AU->isInPreambleFileID(B)) {
401 if (SM.isLoadedSourceLocation(E))
402 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
403 PPRec, *this);
404
405 // Beginning of range lies in the preamble but it also extends beyond
406 // it into the main file. Split the range into 2 parts, one covering
407 // the preamble and another covering the main file. This allows subsequent
408 // calls to visitPreprocessedEntitiesInRange to accept a source range that
409 // lies in the same FileID, allowing it to skip preprocessed entities that
410 // do not come from the same FileID.
411 bool breaked =
412 visitPreprocessedEntitiesInRange(
413 SourceRange(B, AU->getEndOfPreambleFileID()),
414 PPRec, *this);
415 if (breaked) return true;
416 return visitPreprocessedEntitiesInRange(
417 SourceRange(AU->getStartOfMainFileID(), E),
418 PPRec, *this);
419 }
420
421 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
422 }
423
424 bool OnlyLocalDecls
425 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
426
427 if (OnlyLocalDecls)
428 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
429 PPRec);
430
431 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
432}
433
434template<typename InputIterator>
435bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
436 InputIterator Last,
437 PreprocessingRecord &PPRec,
438 FileID FID) {
439 for (; First != Last; ++First) {
440 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
441 continue;
442
443 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000444 if (!PPE)
445 continue;
446
Guy Benyei11169dd2012-12-18 14:30:41 +0000447 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
448 if (Visit(MakeMacroExpansionCursor(ME, TU)))
449 return true;
450
451 continue;
452 }
453
454 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
455 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
456 return true;
457
458 continue;
459 }
460
461 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
462 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
463 return true;
464
465 continue;
466 }
467 }
468
469 return false;
470}
471
472/// \brief Visit the children of the given cursor.
473///
474/// \returns true if the visitation should be aborted, false if it
475/// should continue.
476bool CursorVisitor::VisitChildren(CXCursor Cursor) {
477 if (clang_isReference(Cursor.kind) &&
478 Cursor.kind != CXCursor_CXXBaseSpecifier) {
479 // By definition, references have no children.
480 return false;
481 }
482
483 // Set the Parent field to Cursor, then back to its old value once we're
484 // done.
485 SetParentRAII SetParent(Parent, StmtParent, Cursor);
486
487 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000488 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000489 if (!D)
490 return false;
491
492 return VisitAttributes(D) || Visit(D);
493 }
494
495 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000496 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 return Visit(S);
498
499 return false;
500 }
501
502 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000503 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000504 return Visit(E);
505
506 return false;
507 }
508
509 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000510 CXTranslationUnit TU = getCursorTU(Cursor);
511 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000512
513 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
514 for (unsigned I = 0; I != 2; ++I) {
515 if (VisitOrder[I]) {
516 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
517 RegionOfInterest.isInvalid()) {
518 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
519 TLEnd = CXXUnit->top_level_end();
520 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000521 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000522 return true;
523 }
524 } else if (VisitDeclContext(
525 CXXUnit->getASTContext().getTranslationUnitDecl()))
526 return true;
527 continue;
528 }
529
530 // Walk the preprocessing record.
531 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
532 visitPreprocessedEntitiesInRegion();
533 }
534
535 return false;
536 }
537
538 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000539 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000540 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
541 return Visit(BaseTSInfo->getTypeLoc());
542 }
543 }
544 }
545
546 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000547 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000549 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000550 return Visit(cxcursor::MakeCursorObjCClassRef(
551 ObjT->getInterface(),
552 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000553 }
554
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000555 // If pointing inside a macro definition, check if the token is an identifier
556 // that was ever defined as a macro. In such a case, create a "pseudo" macro
557 // expansion cursor for that token.
558 SourceLocation BeginLoc = RegionOfInterest.getBegin();
559 if (Cursor.kind == CXCursor_MacroDefinition &&
560 BeginLoc == RegionOfInterest.getEnd()) {
561 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000562 const MacroInfo *MI =
563 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000564 if (MacroDefinition *MacroDef =
565 checkForMacroInMacroDefinition(MI, Loc, TU))
566 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
567 }
568
Guy Benyei11169dd2012-12-18 14:30:41 +0000569 // Nothing to visit at the moment.
570 return false;
571}
572
573bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
574 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
575 if (Visit(TSInfo->getTypeLoc()))
576 return true;
577
578 if (Stmt *Body = B->getBody())
579 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
580
581 return false;
582}
583
Ted Kremenek03325582013-02-21 01:29:01 +0000584Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000585 if (RegionOfInterest.isValid()) {
586 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
587 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000588 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000589
590 switch (CompareRegionOfInterest(Range)) {
591 case RangeBefore:
592 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000593 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000594
595 case RangeAfter:
596 // This declaration comes after the region of interest; we're done.
597 return false;
598
599 case RangeOverlap:
600 // This declaration overlaps the region of interest; visit it.
601 break;
602 }
603 }
604 return true;
605}
606
607bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
608 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
609
610 // FIXME: Eventually remove. This part of a hack to support proper
611 // iteration over all Decls contained lexically within an ObjC container.
612 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
613 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
614
615 for ( ; I != E; ++I) {
616 Decl *D = *I;
617 if (D->getLexicalDeclContext() != DC)
618 continue;
619 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
620
621 // Ignore synthesized ivars here, otherwise if we have something like:
622 // @synthesize prop = _prop;
623 // and '_prop' is not declared, we will encounter a '_prop' ivar before
624 // encountering the 'prop' synthesize declaration and we will think that
625 // we passed the region-of-interest.
626 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
627 if (ivarD->getSynthesize())
628 continue;
629 }
630
631 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
632 // declarations is a mismatch with the compiler semantics.
633 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
634 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
635 if (!ID->isThisDeclarationADefinition())
636 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
637
638 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
639 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
640 if (!PD->isThisDeclarationADefinition())
641 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
642 }
643
Ted Kremenek03325582013-02-21 01:29:01 +0000644 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000645 if (!V.hasValue())
646 continue;
647 if (!V.getValue())
648 return false;
649 if (Visit(Cursor, true))
650 return true;
651 }
652 return false;
653}
654
655bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
656 llvm_unreachable("Translation units are visited directly by Visit()");
657}
658
659bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
660 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
661 return Visit(TSInfo->getTypeLoc());
662
663 return false;
664}
665
666bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
667 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
668 return Visit(TSInfo->getTypeLoc());
669
670 return false;
671}
672
673bool CursorVisitor::VisitTagDecl(TagDecl *D) {
674 return VisitDeclContext(D);
675}
676
677bool CursorVisitor::VisitClassTemplateSpecializationDecl(
678 ClassTemplateSpecializationDecl *D) {
679 bool ShouldVisitBody = false;
680 switch (D->getSpecializationKind()) {
681 case TSK_Undeclared:
682 case TSK_ImplicitInstantiation:
683 // Nothing to visit
684 return false;
685
686 case TSK_ExplicitInstantiationDeclaration:
687 case TSK_ExplicitInstantiationDefinition:
688 break;
689
690 case TSK_ExplicitSpecialization:
691 ShouldVisitBody = true;
692 break;
693 }
694
695 // Visit the template arguments used in the specialization.
696 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
697 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000698 if (TemplateSpecializationTypeLoc TSTLoc =
699 TL.getAs<TemplateSpecializationTypeLoc>()) {
700 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
701 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000702 return true;
703 }
704 }
705
706 if (ShouldVisitBody && VisitCXXRecordDecl(D))
707 return true;
708
709 return false;
710}
711
712bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
713 ClassTemplatePartialSpecializationDecl *D) {
714 // FIXME: Visit the "outer" template parameter lists on the TagDecl
715 // before visiting these template parameters.
716 if (VisitTemplateParameters(D->getTemplateParameters()))
717 return true;
718
719 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000720 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
721 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
722 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000723 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
724 return true;
725
726 return VisitCXXRecordDecl(D);
727}
728
729bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
730 // Visit the default argument.
731 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
732 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
733 if (Visit(DefArg->getTypeLoc()))
734 return true;
735
736 return false;
737}
738
739bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
740 if (Expr *Init = D->getInitExpr())
741 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
742 return false;
743}
744
745bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000746 unsigned NumParamList = DD->getNumTemplateParameterLists();
747 for (unsigned i = 0; i < NumParamList; i++) {
748 TemplateParameterList* Params = DD->getTemplateParameterList(i);
749 if (VisitTemplateParameters(Params))
750 return true;
751 }
752
Guy Benyei11169dd2012-12-18 14:30:41 +0000753 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
754 if (Visit(TSInfo->getTypeLoc()))
755 return true;
756
757 // Visit the nested-name-specifier, if present.
758 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
759 if (VisitNestedNameSpecifierLoc(QualifierLoc))
760 return true;
761
762 return false;
763}
764
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000765/// \brief Compare two base or member initializers based on their source order.
766static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
767 CXXCtorInitializer *const *Y) {
768 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
769}
770
Guy Benyei11169dd2012-12-18 14:30:41 +0000771bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000772 unsigned NumParamList = ND->getNumTemplateParameterLists();
773 for (unsigned i = 0; i < NumParamList; i++) {
774 TemplateParameterList* Params = ND->getTemplateParameterList(i);
775 if (VisitTemplateParameters(Params))
776 return true;
777 }
778
Guy Benyei11169dd2012-12-18 14:30:41 +0000779 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
780 // Visit the function declaration's syntactic components in the order
781 // written. This requires a bit of work.
782 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000783 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000784
785 // If we have a function declared directly (without the use of a typedef),
786 // visit just the return type. Otherwise, just visit the function's type
787 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000788 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000789 (!FTL && Visit(TL)))
790 return true;
791
792 // Visit the nested-name-specifier, if present.
793 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
794 if (VisitNestedNameSpecifierLoc(QualifierLoc))
795 return true;
796
797 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000798 if (!isa<CXXDestructorDecl>(ND))
799 if (VisitDeclarationNameInfo(ND->getNameInfo()))
800 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000801
802 // FIXME: Visit explicitly-specified template arguments!
803
804 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000805 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000806 return true;
807
Bill Wendling44426052012-12-20 19:22:21 +0000808 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000809 }
810
811 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
812 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
813 // Find the initializers that were written in the source.
814 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000815 for (auto *I : Constructor->inits()) {
816 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000817 continue;
818
Aaron Ballman0ad78302014-03-13 17:34:31 +0000819 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000820 }
821
822 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000823 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
824 &CompareCXXCtorInitializers);
825
Guy Benyei11169dd2012-12-18 14:30:41 +0000826 // Visit the initializers in source order
827 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
828 CXXCtorInitializer *Init = WrittenInits[I];
829 if (Init->isAnyMemberInitializer()) {
830 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
831 Init->getMemberLocation(), TU)))
832 return true;
833 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
834 if (Visit(TInfo->getTypeLoc()))
835 return true;
836 }
837
838 // Visit the initializer value.
839 if (Expr *Initializer = Init->getInit())
840 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
841 return true;
842 }
843 }
844
845 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
846 return true;
847 }
848
849 return false;
850}
851
852bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
853 if (VisitDeclaratorDecl(D))
854 return true;
855
856 if (Expr *BitWidth = D->getBitWidth())
857 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
858
859 return false;
860}
861
862bool CursorVisitor::VisitVarDecl(VarDecl *D) {
863 if (VisitDeclaratorDecl(D))
864 return true;
865
866 if (Expr *Init = D->getInit())
867 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
868
869 return false;
870}
871
872bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
873 if (VisitDeclaratorDecl(D))
874 return true;
875
876 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
877 if (Expr *DefArg = D->getDefaultArgument())
878 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
879
880 return false;
881}
882
883bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
884 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
885 // before visiting these template parameters.
886 if (VisitTemplateParameters(D->getTemplateParameters()))
887 return true;
888
889 return VisitFunctionDecl(D->getTemplatedDecl());
890}
891
892bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
893 // FIXME: Visit the "outer" template parameter lists on the TagDecl
894 // before visiting these template parameters.
895 if (VisitTemplateParameters(D->getTemplateParameters()))
896 return true;
897
898 return VisitCXXRecordDecl(D->getTemplatedDecl());
899}
900
901bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
902 if (VisitTemplateParameters(D->getTemplateParameters()))
903 return true;
904
905 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
906 VisitTemplateArgumentLoc(D->getDefaultArgument()))
907 return true;
908
909 return false;
910}
911
912bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000913 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000914 if (Visit(TSInfo->getTypeLoc()))
915 return true;
916
Aaron Ballman43b68be2014-03-07 17:50:17 +0000917 for (const auto *P : ND->params()) {
918 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000919 return true;
920 }
921
922 if (ND->isThisDeclarationADefinition() &&
923 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
924 return true;
925
926 return false;
927}
928
929template <typename DeclIt>
930static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
931 SourceManager &SM, SourceLocation EndLoc,
932 SmallVectorImpl<Decl *> &Decls) {
933 DeclIt next = *DI_current;
934 while (++next != DE_current) {
935 Decl *D_next = *next;
936 if (!D_next)
937 break;
938 SourceLocation L = D_next->getLocStart();
939 if (!L.isValid())
940 break;
941 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
942 *DI_current = next;
943 Decls.push_back(D_next);
944 continue;
945 }
946 break;
947 }
948}
949
Guy Benyei11169dd2012-12-18 14:30:41 +0000950bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
951 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
952 // an @implementation can lexically contain Decls that are not properly
953 // nested in the AST. When we identify such cases, we need to retrofit
954 // this nesting here.
955 if (!DI_current && !FileDI_current)
956 return VisitDeclContext(D);
957
958 // Scan the Decls that immediately come after the container
959 // in the current DeclContext. If any fall within the
960 // container's lexical region, stash them into a vector
961 // for later processing.
962 SmallVector<Decl *, 24> DeclsInContainer;
963 SourceLocation EndLoc = D->getSourceRange().getEnd();
964 SourceManager &SM = AU->getSourceManager();
965 if (EndLoc.isValid()) {
966 if (DI_current) {
967 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
968 DeclsInContainer);
969 } else {
970 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
971 DeclsInContainer);
972 }
973 }
974
975 // The common case.
976 if (DeclsInContainer.empty())
977 return VisitDeclContext(D);
978
979 // Get all the Decls in the DeclContext, and sort them with the
980 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000981 for (auto *SubDecl : D->decls()) {
982 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
983 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000984 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000985 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000986 }
987
988 // Now sort the Decls so that they appear in lexical order.
989 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000990 [&SM](Decl *A, Decl *B) {
991 SourceLocation L_A = A->getLocStart();
992 SourceLocation L_B = B->getLocStart();
993 assert(L_A.isValid() && L_B.isValid());
994 return SM.isBeforeInTranslationUnit(L_A, L_B);
995 });
Guy Benyei11169dd2012-12-18 14:30:41 +0000996
997 // Now visit the decls.
998 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
999 E = DeclsInContainer.end(); I != E; ++I) {
1000 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001001 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001002 if (!V.hasValue())
1003 continue;
1004 if (!V.getValue())
1005 return false;
1006 if (Visit(Cursor, true))
1007 return true;
1008 }
1009 return false;
1010}
1011
1012bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1013 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1014 TU)))
1015 return true;
1016
1017 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1018 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1019 E = ND->protocol_end(); I != E; ++I, ++PL)
1020 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1021 return true;
1022
1023 return VisitObjCContainerDecl(ND);
1024}
1025
1026bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1027 if (!PID->isThisDeclarationADefinition())
1028 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1029
1030 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1031 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1032 E = PID->protocol_end(); I != E; ++I, ++PL)
1033 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1034 return true;
1035
1036 return VisitObjCContainerDecl(PID);
1037}
1038
1039bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1040 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1041 return true;
1042
1043 // FIXME: This implements a workaround with @property declarations also being
1044 // installed in the DeclContext for the @interface. Eventually this code
1045 // should be removed.
1046 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1047 if (!CDecl || !CDecl->IsClassExtension())
1048 return false;
1049
1050 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1051 if (!ID)
1052 return false;
1053
1054 IdentifierInfo *PropertyId = PD->getIdentifier();
1055 ObjCPropertyDecl *prevDecl =
1056 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1057
1058 if (!prevDecl)
1059 return false;
1060
1061 // Visit synthesized methods since they will be skipped when visiting
1062 // the @interface.
1063 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1064 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1065 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1066 return true;
1067
1068 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1069 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1070 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1071 return true;
1072
1073 return false;
1074}
1075
1076bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1077 if (!D->isThisDeclarationADefinition()) {
1078 // Forward declaration is treated like a reference.
1079 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1080 }
1081
1082 // Issue callbacks for super class.
1083 if (D->getSuperClass() &&
1084 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1085 D->getSuperClassLoc(),
1086 TU)))
1087 return true;
1088
1089 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1090 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1091 E = D->protocol_end(); I != E; ++I, ++PL)
1092 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1093 return true;
1094
1095 return VisitObjCContainerDecl(D);
1096}
1097
1098bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1099 return VisitObjCContainerDecl(D);
1100}
1101
1102bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1103 // 'ID' could be null when dealing with invalid code.
1104 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1105 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1106 return true;
1107
1108 return VisitObjCImplDecl(D);
1109}
1110
1111bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1112#if 0
1113 // Issue callbacks for super class.
1114 // FIXME: No source location information!
1115 if (D->getSuperClass() &&
1116 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1117 D->getSuperClassLoc(),
1118 TU)))
1119 return true;
1120#endif
1121
1122 return VisitObjCImplDecl(D);
1123}
1124
1125bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1126 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1127 if (PD->isIvarNameSpecified())
1128 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1129
1130 return false;
1131}
1132
1133bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1134 return VisitDeclContext(D);
1135}
1136
1137bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1138 // Visit nested-name-specifier.
1139 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1140 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1141 return true;
1142
1143 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1144 D->getTargetNameLoc(), TU));
1145}
1146
1147bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1148 // Visit nested-name-specifier.
1149 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1150 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1151 return true;
1152 }
1153
1154 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1155 return true;
1156
1157 return VisitDeclarationNameInfo(D->getNameInfo());
1158}
1159
1160bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1161 // Visit nested-name-specifier.
1162 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1163 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1164 return true;
1165
1166 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1167 D->getIdentLocation(), TU));
1168}
1169
1170bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1171 // Visit nested-name-specifier.
1172 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1173 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1174 return true;
1175 }
1176
1177 return VisitDeclarationNameInfo(D->getNameInfo());
1178}
1179
1180bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1181 UnresolvedUsingTypenameDecl *D) {
1182 // Visit nested-name-specifier.
1183 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1184 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1185 return true;
1186
1187 return false;
1188}
1189
1190bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1191 switch (Name.getName().getNameKind()) {
1192 case clang::DeclarationName::Identifier:
1193 case clang::DeclarationName::CXXLiteralOperatorName:
1194 case clang::DeclarationName::CXXOperatorName:
1195 case clang::DeclarationName::CXXUsingDirective:
1196 return false;
1197
1198 case clang::DeclarationName::CXXConstructorName:
1199 case clang::DeclarationName::CXXDestructorName:
1200 case clang::DeclarationName::CXXConversionFunctionName:
1201 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1202 return Visit(TSInfo->getTypeLoc());
1203 return false;
1204
1205 case clang::DeclarationName::ObjCZeroArgSelector:
1206 case clang::DeclarationName::ObjCOneArgSelector:
1207 case clang::DeclarationName::ObjCMultiArgSelector:
1208 // FIXME: Per-identifier location info?
1209 return false;
1210 }
1211
1212 llvm_unreachable("Invalid DeclarationName::Kind!");
1213}
1214
1215bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1216 SourceRange Range) {
1217 // FIXME: This whole routine is a hack to work around the lack of proper
1218 // source information in nested-name-specifiers (PR5791). Since we do have
1219 // a beginning source location, we can visit the first component of the
1220 // nested-name-specifier, if it's a single-token component.
1221 if (!NNS)
1222 return false;
1223
1224 // Get the first component in the nested-name-specifier.
1225 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1226 NNS = Prefix;
1227
1228 switch (NNS->getKind()) {
1229 case NestedNameSpecifier::Namespace:
1230 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1231 TU));
1232
1233 case NestedNameSpecifier::NamespaceAlias:
1234 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1235 Range.getBegin(), TU));
1236
1237 case NestedNameSpecifier::TypeSpec: {
1238 // If the type has a form where we know that the beginning of the source
1239 // range matches up with a reference cursor. Visit the appropriate reference
1240 // cursor.
1241 const Type *T = NNS->getAsType();
1242 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1243 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1244 if (const TagType *Tag = dyn_cast<TagType>(T))
1245 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1246 if (const TemplateSpecializationType *TST
1247 = dyn_cast<TemplateSpecializationType>(T))
1248 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1249 break;
1250 }
1251
1252 case NestedNameSpecifier::TypeSpecWithTemplate:
1253 case NestedNameSpecifier::Global:
1254 case NestedNameSpecifier::Identifier:
1255 break;
1256 }
1257
1258 return false;
1259}
1260
1261bool
1262CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1263 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1264 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1265 Qualifiers.push_back(Qualifier);
1266
1267 while (!Qualifiers.empty()) {
1268 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1269 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1270 switch (NNS->getKind()) {
1271 case NestedNameSpecifier::Namespace:
1272 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1273 Q.getLocalBeginLoc(),
1274 TU)))
1275 return true;
1276
1277 break;
1278
1279 case NestedNameSpecifier::NamespaceAlias:
1280 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1281 Q.getLocalBeginLoc(),
1282 TU)))
1283 return true;
1284
1285 break;
1286
1287 case NestedNameSpecifier::TypeSpec:
1288 case NestedNameSpecifier::TypeSpecWithTemplate:
1289 if (Visit(Q.getTypeLoc()))
1290 return true;
1291
1292 break;
1293
1294 case NestedNameSpecifier::Global:
1295 case NestedNameSpecifier::Identifier:
1296 break;
1297 }
1298 }
1299
1300 return false;
1301}
1302
1303bool CursorVisitor::VisitTemplateParameters(
1304 const TemplateParameterList *Params) {
1305 if (!Params)
1306 return false;
1307
1308 for (TemplateParameterList::const_iterator P = Params->begin(),
1309 PEnd = Params->end();
1310 P != PEnd; ++P) {
1311 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1312 return true;
1313 }
1314
1315 return false;
1316}
1317
1318bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1319 switch (Name.getKind()) {
1320 case TemplateName::Template:
1321 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1322
1323 case TemplateName::OverloadedTemplate:
1324 // Visit the overloaded template set.
1325 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1326 return true;
1327
1328 return false;
1329
1330 case TemplateName::DependentTemplate:
1331 // FIXME: Visit nested-name-specifier.
1332 return false;
1333
1334 case TemplateName::QualifiedTemplate:
1335 // FIXME: Visit nested-name-specifier.
1336 return Visit(MakeCursorTemplateRef(
1337 Name.getAsQualifiedTemplateName()->getDecl(),
1338 Loc, TU));
1339
1340 case TemplateName::SubstTemplateTemplateParm:
1341 return Visit(MakeCursorTemplateRef(
1342 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1343 Loc, TU));
1344
1345 case TemplateName::SubstTemplateTemplateParmPack:
1346 return Visit(MakeCursorTemplateRef(
1347 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1348 Loc, TU));
1349 }
1350
1351 llvm_unreachable("Invalid TemplateName::Kind!");
1352}
1353
1354bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1355 switch (TAL.getArgument().getKind()) {
1356 case TemplateArgument::Null:
1357 case TemplateArgument::Integral:
1358 case TemplateArgument::Pack:
1359 return false;
1360
1361 case TemplateArgument::Type:
1362 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1363 return Visit(TSInfo->getTypeLoc());
1364 return false;
1365
1366 case TemplateArgument::Declaration:
1367 if (Expr *E = TAL.getSourceDeclExpression())
1368 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1369 return false;
1370
1371 case TemplateArgument::NullPtr:
1372 if (Expr *E = TAL.getSourceNullPtrExpression())
1373 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1374 return false;
1375
1376 case TemplateArgument::Expression:
1377 if (Expr *E = TAL.getSourceExpression())
1378 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1379 return false;
1380
1381 case TemplateArgument::Template:
1382 case TemplateArgument::TemplateExpansion:
1383 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1384 return true;
1385
1386 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1387 TAL.getTemplateNameLoc());
1388 }
1389
1390 llvm_unreachable("Invalid TemplateArgument::Kind!");
1391}
1392
1393bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1394 return VisitDeclContext(D);
1395}
1396
1397bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1398 return Visit(TL.getUnqualifiedLoc());
1399}
1400
1401bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1402 ASTContext &Context = AU->getASTContext();
1403
1404 // Some builtin types (such as Objective-C's "id", "sel", and
1405 // "Class") have associated declarations. Create cursors for those.
1406 QualType VisitType;
1407 switch (TL.getTypePtr()->getKind()) {
1408
1409 case BuiltinType::Void:
1410 case BuiltinType::NullPtr:
1411 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001412 case BuiltinType::OCLImage1d:
1413 case BuiltinType::OCLImage1dArray:
1414 case BuiltinType::OCLImage1dBuffer:
1415 case BuiltinType::OCLImage2d:
1416 case BuiltinType::OCLImage2dArray:
1417 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001418 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001419 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001420#define BUILTIN_TYPE(Id, SingletonId)
1421#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1422#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1423#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1424#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1425#include "clang/AST/BuiltinTypes.def"
1426 break;
1427
1428 case BuiltinType::ObjCId:
1429 VisitType = Context.getObjCIdType();
1430 break;
1431
1432 case BuiltinType::ObjCClass:
1433 VisitType = Context.getObjCClassType();
1434 break;
1435
1436 case BuiltinType::ObjCSel:
1437 VisitType = Context.getObjCSelType();
1438 break;
1439 }
1440
1441 if (!VisitType.isNull()) {
1442 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1443 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1444 TU));
1445 }
1446
1447 return false;
1448}
1449
1450bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1451 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1452}
1453
1454bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1455 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1456}
1457
1458bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1459 if (TL.isDefinition())
1460 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1461
1462 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1463}
1464
1465bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1466 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1467}
1468
1469bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1470 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1471 return true;
1472
1473 return false;
1474}
1475
1476bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1477 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1478 return true;
1479
1480 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1481 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1482 TU)))
1483 return true;
1484 }
1485
1486 return false;
1487}
1488
1489bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1490 return Visit(TL.getPointeeLoc());
1491}
1492
1493bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1494 return Visit(TL.getInnerLoc());
1495}
1496
1497bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1498 return Visit(TL.getPointeeLoc());
1499}
1500
1501bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1502 return Visit(TL.getPointeeLoc());
1503}
1504
1505bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1506 return Visit(TL.getPointeeLoc());
1507}
1508
1509bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1510 return Visit(TL.getPointeeLoc());
1511}
1512
1513bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1514 return Visit(TL.getPointeeLoc());
1515}
1516
1517bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1518 return Visit(TL.getModifiedLoc());
1519}
1520
1521bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1522 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001523 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001524 return true;
1525
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001526 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1527 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001528 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1529 return true;
1530
1531 return false;
1532}
1533
1534bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1535 if (Visit(TL.getElementLoc()))
1536 return true;
1537
1538 if (Expr *Size = TL.getSizeExpr())
1539 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1540
1541 return false;
1542}
1543
Reid Kleckner8a365022013-06-24 17:51:48 +00001544bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1545 return Visit(TL.getOriginalLoc());
1546}
1547
Reid Kleckner0503a872013-12-05 01:23:43 +00001548bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1549 return Visit(TL.getOriginalLoc());
1550}
1551
Guy Benyei11169dd2012-12-18 14:30:41 +00001552bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1553 TemplateSpecializationTypeLoc TL) {
1554 // Visit the template name.
1555 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1556 TL.getTemplateNameLoc()))
1557 return true;
1558
1559 // Visit the template arguments.
1560 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1561 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1562 return true;
1563
1564 return false;
1565}
1566
1567bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1568 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1569}
1570
1571bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1572 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1573 return Visit(TSInfo->getTypeLoc());
1574
1575 return false;
1576}
1577
1578bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1579 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1580 return Visit(TSInfo->getTypeLoc());
1581
1582 return false;
1583}
1584
1585bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1586 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1587 return true;
1588
1589 return false;
1590}
1591
1592bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1593 DependentTemplateSpecializationTypeLoc TL) {
1594 // Visit the nested-name-specifier, if there is one.
1595 if (TL.getQualifierLoc() &&
1596 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1597 return true;
1598
1599 // Visit the template arguments.
1600 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1601 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1602 return true;
1603
1604 return false;
1605}
1606
1607bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1608 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1609 return true;
1610
1611 return Visit(TL.getNamedTypeLoc());
1612}
1613
1614bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1615 return Visit(TL.getPatternLoc());
1616}
1617
1618bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1619 if (Expr *E = TL.getUnderlyingExpr())
1620 return Visit(MakeCXCursor(E, StmtParent, TU));
1621
1622 return false;
1623}
1624
1625bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1626 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1627}
1628
1629bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1630 return Visit(TL.getValueLoc());
1631}
1632
1633#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1634bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1635 return Visit##PARENT##Loc(TL); \
1636}
1637
1638DEFAULT_TYPELOC_IMPL(Complex, Type)
1639DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1640DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1641DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1642DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1643DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1644DEFAULT_TYPELOC_IMPL(Vector, Type)
1645DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1646DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1647DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1648DEFAULT_TYPELOC_IMPL(Record, TagType)
1649DEFAULT_TYPELOC_IMPL(Enum, TagType)
1650DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1651DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1652DEFAULT_TYPELOC_IMPL(Auto, Type)
1653
1654bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1655 // Visit the nested-name-specifier, if present.
1656 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1657 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1658 return true;
1659
1660 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001661 for (const auto &I : D->bases()) {
1662 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001663 return true;
1664 }
1665 }
1666
1667 return VisitTagDecl(D);
1668}
1669
1670bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001671 for (const auto *I : D->attrs())
1672 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001673 return true;
1674
1675 return false;
1676}
1677
1678//===----------------------------------------------------------------------===//
1679// Data-recursive visitor methods.
1680//===----------------------------------------------------------------------===//
1681
1682namespace {
1683#define DEF_JOB(NAME, DATA, KIND)\
1684class NAME : public VisitorJob {\
1685public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001686 NAME(const DATA *d, CXCursor parent) : \
1687 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001688 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001689 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001690};
1691
1692DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1693DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1694DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1695DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1696DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1697 ExplicitTemplateArgsVisitKind)
1698DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1699DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1700DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1701#undef DEF_JOB
1702
1703class DeclVisit : public VisitorJob {
1704public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001705 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001706 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001707 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001708 static bool classof(const VisitorJob *VJ) {
1709 return VJ->getKind() == DeclVisitKind;
1710 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001711 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001712 bool isFirst() const { return data[1] ? true : false; }
1713};
1714class TypeLocVisit : public VisitorJob {
1715public:
1716 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1717 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1718 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1719
1720 static bool classof(const VisitorJob *VJ) {
1721 return VJ->getKind() == TypeLocVisitKind;
1722 }
1723
1724 TypeLoc get() const {
1725 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001726 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001727 }
1728};
1729
1730class LabelRefVisit : public VisitorJob {
1731public:
1732 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1733 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1734 labelLoc.getPtrEncoding()) {}
1735
1736 static bool classof(const VisitorJob *VJ) {
1737 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1738 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001739 const LabelDecl *get() const {
1740 return static_cast<const LabelDecl *>(data[0]);
1741 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001742 SourceLocation getLoc() const {
1743 return SourceLocation::getFromPtrEncoding(data[1]); }
1744};
1745
1746class NestedNameSpecifierLocVisit : public VisitorJob {
1747public:
1748 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1749 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1750 Qualifier.getNestedNameSpecifier(),
1751 Qualifier.getOpaqueData()) { }
1752
1753 static bool classof(const VisitorJob *VJ) {
1754 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1755 }
1756
1757 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001758 return NestedNameSpecifierLoc(
1759 const_cast<NestedNameSpecifier *>(
1760 static_cast<const NestedNameSpecifier *>(data[0])),
1761 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001762 }
1763};
1764
1765class DeclarationNameInfoVisit : public VisitorJob {
1766public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001767 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001768 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001769 static bool classof(const VisitorJob *VJ) {
1770 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1771 }
1772 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001773 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001774 switch (S->getStmtClass()) {
1775 default:
1776 llvm_unreachable("Unhandled Stmt");
1777 case clang::Stmt::MSDependentExistsStmtClass:
1778 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1779 case Stmt::CXXDependentScopeMemberExprClass:
1780 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1781 case Stmt::DependentScopeDeclRefExprClass:
1782 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1783 }
1784 }
1785};
1786class MemberRefVisit : public VisitorJob {
1787public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001788 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001789 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1790 L.getPtrEncoding()) {}
1791 static bool classof(const VisitorJob *VJ) {
1792 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1793 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001794 const FieldDecl *get() const {
1795 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001796 }
1797 SourceLocation getLoc() const {
1798 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1799 }
1800};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001801class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001802 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001803 VisitorWorkList &WL;
1804 CXCursor Parent;
1805public:
1806 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1807 : WL(wl), Parent(parent) {}
1808
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001809 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1810 void VisitBlockExpr(const BlockExpr *B);
1811 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1812 void VisitCompoundStmt(const CompoundStmt *S);
1813 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1814 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1815 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1816 void VisitCXXNewExpr(const CXXNewExpr *E);
1817 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1818 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1819 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1820 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1821 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1822 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1823 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1824 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1825 void VisitDeclRefExpr(const DeclRefExpr *D);
1826 void VisitDeclStmt(const DeclStmt *S);
1827 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1828 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1829 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1830 void VisitForStmt(const ForStmt *FS);
1831 void VisitGotoStmt(const GotoStmt *GS);
1832 void VisitIfStmt(const IfStmt *If);
1833 void VisitInitListExpr(const InitListExpr *IE);
1834 void VisitMemberExpr(const MemberExpr *M);
1835 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1836 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1837 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1838 void VisitOverloadExpr(const OverloadExpr *E);
1839 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1840 void VisitStmt(const Stmt *S);
1841 void VisitSwitchStmt(const SwitchStmt *S);
1842 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001843 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1844 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1845 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1846 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1847 void VisitVAArgExpr(const VAArgExpr *E);
1848 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1849 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1850 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1851 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001852 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1853 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001854 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001855
Guy Benyei11169dd2012-12-18 14:30:41 +00001856private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001857 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001858 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1859 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001860 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1861 void AddStmt(const Stmt *S);
1862 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001863 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001864 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001865 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001866};
1867} // end anonyous namespace
1868
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001869void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001870 // 'S' should always be non-null, since it comes from the
1871 // statement we are visiting.
1872 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1873}
1874
1875void
1876EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1877 if (Qualifier)
1878 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1879}
1880
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001881void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001882 if (S)
1883 WL.push_back(StmtVisit(S, Parent));
1884}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001885void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001886 if (D)
1887 WL.push_back(DeclVisit(D, Parent, isFirst));
1888}
1889void EnqueueVisitor::
1890 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1891 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001892 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001893}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001894void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001895 if (D)
1896 WL.push_back(MemberRefVisit(D, L, Parent));
1897}
1898void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1899 if (TI)
1900 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1901 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001903 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001904 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001905 AddStmt(*Child);
1906 }
1907 if (size == WL.size())
1908 return;
1909 // Now reverse the entries we just added. This will match the DFS
1910 // ordering performed by the worklist.
1911 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1912 std::reverse(I, E);
1913}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001914namespace {
1915class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1916 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001917 /// \brief Process clauses with list of variables.
1918 template <typename T>
1919 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001920public:
1921 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1922#define OPENMP_CLAUSE(Name, Class) \
1923 void Visit##Class(const Class *C);
1924#include "clang/Basic/OpenMPKinds.def"
1925};
1926
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001927void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1928 Visitor->AddStmt(C->getCondition());
1929}
1930
Alexey Bataev568a8332014-03-06 06:15:19 +00001931void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1932 Visitor->AddStmt(C->getNumThreads());
1933}
1934
Alexey Bataev62c87d22014-03-21 04:51:18 +00001935void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1936 Visitor->AddStmt(C->getSafelen());
1937}
1938
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001939void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001940
1941template<typename T>
1942void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001943 for (const auto *I : Node->varlists())
1944 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001945}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001946
1947void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001948 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001949}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001950void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1951 const OMPFirstprivateClause *C) {
1952 VisitOMPClauseList(C);
1953}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001954void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001955 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001956}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00001957void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
1958 VisitOMPClauseList(C);
1959}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001960}
Alexey Bataev756c1962013-09-24 03:17:45 +00001961
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001962void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1963 unsigned size = WL.size();
1964 OMPClauseEnqueue Visitor(this);
1965 Visitor.Visit(S);
1966 if (size == WL.size())
1967 return;
1968 // Now reverse the entries we just added. This will match the DFS
1969 // ordering performed by the worklist.
1970 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1971 std::reverse(I, E);
1972}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001973void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001974 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1975}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001976void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001977 AddDecl(B->getBlockDecl());
1978}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001979void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001980 EnqueueChildren(E);
1981 AddTypeLoc(E->getTypeSourceInfo());
1982}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001983void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1984 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001985 E = S->body_rend(); I != E; ++I) {
1986 AddStmt(*I);
1987 }
1988}
1989void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001990VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001991 AddStmt(S->getSubStmt());
1992 AddDeclarationNameInfo(S);
1993 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1994 AddNestedNameSpecifierLoc(QualifierLoc);
1995}
1996
1997void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001998VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001999 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2000 AddDeclarationNameInfo(E);
2001 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2002 AddNestedNameSpecifierLoc(QualifierLoc);
2003 if (!E->isImplicitAccess())
2004 AddStmt(E->getBase());
2005}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002006void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002007 // Enqueue the initializer , if any.
2008 AddStmt(E->getInitializer());
2009 // Enqueue the array size, if any.
2010 AddStmt(E->getArraySize());
2011 // Enqueue the allocated type.
2012 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2013 // Enqueue the placement arguments.
2014 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2015 AddStmt(E->getPlacementArg(I-1));
2016}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002017void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002018 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2019 AddStmt(CE->getArg(I-1));
2020 AddStmt(CE->getCallee());
2021 AddStmt(CE->getArg(0));
2022}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002023void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2024 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002025 // Visit the name of the type being destroyed.
2026 AddTypeLoc(E->getDestroyedTypeInfo());
2027 // Visit the scope type that looks disturbingly like the nested-name-specifier
2028 // but isn't.
2029 AddTypeLoc(E->getScopeTypeInfo());
2030 // Visit the nested-name-specifier.
2031 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2032 AddNestedNameSpecifierLoc(QualifierLoc);
2033 // Visit base expression.
2034 AddStmt(E->getBase());
2035}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002036void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2037 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002038 AddTypeLoc(E->getTypeSourceInfo());
2039}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002040void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2041 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002042 EnqueueChildren(E);
2043 AddTypeLoc(E->getTypeSourceInfo());
2044}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002045void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002046 EnqueueChildren(E);
2047 if (E->isTypeOperand())
2048 AddTypeLoc(E->getTypeOperandSourceInfo());
2049}
2050
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002051void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2052 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002053 EnqueueChildren(E);
2054 AddTypeLoc(E->getTypeSourceInfo());
2055}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002056void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002057 EnqueueChildren(E);
2058 if (E->isTypeOperand())
2059 AddTypeLoc(E->getTypeOperandSourceInfo());
2060}
2061
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002062void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002063 EnqueueChildren(S);
2064 AddDecl(S->getExceptionDecl());
2065}
2066
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002067void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002068 if (DR->hasExplicitTemplateArgs()) {
2069 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2070 }
2071 WL.push_back(DeclRefExprParts(DR, Parent));
2072}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002073void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2074 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002075 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2076 AddDeclarationNameInfo(E);
2077 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2078}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002079void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002080 unsigned size = WL.size();
2081 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002082 for (const auto *D : S->decls()) {
2083 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002084 isFirst = false;
2085 }
2086 if (size == WL.size())
2087 return;
2088 // Now reverse the entries we just added. This will match the DFS
2089 // ordering performed by the worklist.
2090 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2091 std::reverse(I, E);
2092}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002093void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002094 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002095 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002096 D = E->designators_rbegin(), DEnd = E->designators_rend();
2097 D != DEnd; ++D) {
2098 if (D->isFieldDesignator()) {
2099 if (FieldDecl *Field = D->getField())
2100 AddMemberRef(Field, D->getFieldLoc());
2101 continue;
2102 }
2103 if (D->isArrayDesignator()) {
2104 AddStmt(E->getArrayIndex(*D));
2105 continue;
2106 }
2107 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2108 AddStmt(E->getArrayRangeEnd(*D));
2109 AddStmt(E->getArrayRangeStart(*D));
2110 }
2111}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002112void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002113 EnqueueChildren(E);
2114 AddTypeLoc(E->getTypeInfoAsWritten());
2115}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002116void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002117 AddStmt(FS->getBody());
2118 AddStmt(FS->getInc());
2119 AddStmt(FS->getCond());
2120 AddDecl(FS->getConditionVariable());
2121 AddStmt(FS->getInit());
2122}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002123void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002124 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2125}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002126void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002127 AddStmt(If->getElse());
2128 AddStmt(If->getThen());
2129 AddStmt(If->getCond());
2130 AddDecl(If->getConditionVariable());
2131}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002132void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002133 // We care about the syntactic form of the initializer list, only.
2134 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2135 IE = Syntactic;
2136 EnqueueChildren(IE);
2137}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002138void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002139 WL.push_back(MemberExprParts(M, Parent));
2140
2141 // If the base of the member access expression is an implicit 'this', don't
2142 // visit it.
2143 // FIXME: If we ever want to show these implicit accesses, this will be
2144 // unfortunate. However, clang_getCursor() relies on this behavior.
2145 if (!M->isImplicitAccess())
2146 AddStmt(M->getBase());
2147}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002148void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002149 AddTypeLoc(E->getEncodedTypeSourceInfo());
2150}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002151void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002152 EnqueueChildren(M);
2153 AddTypeLoc(M->getClassReceiverTypeInfo());
2154}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002155void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002156 // Visit the components of the offsetof expression.
2157 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2158 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2159 const OffsetOfNode &Node = E->getComponent(I-1);
2160 switch (Node.getKind()) {
2161 case OffsetOfNode::Array:
2162 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2163 break;
2164 case OffsetOfNode::Field:
2165 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2166 break;
2167 case OffsetOfNode::Identifier:
2168 case OffsetOfNode::Base:
2169 continue;
2170 }
2171 }
2172 // Visit the type into which we're computing the offset.
2173 AddTypeLoc(E->getTypeSourceInfo());
2174}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002175void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002176 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2177 WL.push_back(OverloadExprParts(E, Parent));
2178}
2179void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002180 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002181 EnqueueChildren(E);
2182 if (E->isArgumentType())
2183 AddTypeLoc(E->getArgumentTypeInfo());
2184}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002185void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002186 EnqueueChildren(S);
2187}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002188void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002189 AddStmt(S->getBody());
2190 AddStmt(S->getCond());
2191 AddDecl(S->getConditionVariable());
2192}
2193
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002194void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002195 AddStmt(W->getBody());
2196 AddStmt(W->getCond());
2197 AddDecl(W->getConditionVariable());
2198}
2199
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002200void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002201 for (unsigned I = E->getNumArgs(); I > 0; --I)
2202 AddTypeLoc(E->getArg(I-1));
2203}
2204
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002205void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002206 AddTypeLoc(E->getQueriedTypeSourceInfo());
2207}
2208
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002209void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002210 EnqueueChildren(E);
2211}
2212
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002213void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002214 VisitOverloadExpr(U);
2215 if (!U->isImplicitAccess())
2216 AddStmt(U->getBase());
2217}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 AddStmt(E->getSubExpr());
2220 AddTypeLoc(E->getWrittenTypeInfo());
2221}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002222void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002223 WL.push_back(SizeOfPackExprParts(E, Parent));
2224}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002225void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002226 // If the opaque value has a source expression, just transparently
2227 // visit that. This is useful for (e.g.) pseudo-object expressions.
2228 if (Expr *SourceExpr = E->getSourceExpr())
2229 return Visit(SourceExpr);
2230}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002231void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002232 AddStmt(E->getBody());
2233 WL.push_back(LambdaExprParts(E, Parent));
2234}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002235void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002236 // Treat the expression like its syntactic form.
2237 Visit(E->getSyntacticForm());
2238}
2239
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002240void EnqueueVisitor::VisitOMPExecutableDirective(
2241 const OMPExecutableDirective *D) {
2242 EnqueueChildren(D);
2243 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2244 E = D->clauses().end();
2245 I != E; ++I)
2246 EnqueueChildren(*I);
2247}
2248
2249void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2250 VisitOMPExecutableDirective(D);
2251}
2252
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002253void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2254 VisitOMPExecutableDirective(D);
2255}
2256
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002257void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002258 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2259}
2260
2261bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2262 if (RegionOfInterest.isValid()) {
2263 SourceRange Range = getRawCursorExtent(C);
2264 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2265 return false;
2266 }
2267 return true;
2268}
2269
2270bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2271 while (!WL.empty()) {
2272 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002273 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002274
2275 // Set the Parent field, then back to its old value once we're done.
2276 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2277
2278 switch (LI.getKind()) {
2279 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002280 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002281 if (!D)
2282 continue;
2283
2284 // For now, perform default visitation for Decls.
2285 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2286 cast<DeclVisit>(&LI)->isFirst())))
2287 return true;
2288
2289 continue;
2290 }
2291 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2292 const ASTTemplateArgumentListInfo *ArgList =
2293 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2294 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2295 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2296 Arg != ArgEnd; ++Arg) {
2297 if (VisitTemplateArgumentLoc(*Arg))
2298 return true;
2299 }
2300 continue;
2301 }
2302 case VisitorJob::TypeLocVisitKind: {
2303 // Perform default visitation for TypeLocs.
2304 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2305 return true;
2306 continue;
2307 }
2308 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002309 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002310 if (LabelStmt *stmt = LS->getStmt()) {
2311 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2312 TU))) {
2313 return true;
2314 }
2315 }
2316 continue;
2317 }
2318
2319 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2320 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2321 if (VisitNestedNameSpecifierLoc(V->get()))
2322 return true;
2323 continue;
2324 }
2325
2326 case VisitorJob::DeclarationNameInfoVisitKind: {
2327 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2328 ->get()))
2329 return true;
2330 continue;
2331 }
2332 case VisitorJob::MemberRefVisitKind: {
2333 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2334 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2335 return true;
2336 continue;
2337 }
2338 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002339 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002340 if (!S)
2341 continue;
2342
2343 // Update the current cursor.
2344 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2345 if (!IsInRegionOfInterest(Cursor))
2346 continue;
2347 switch (Visitor(Cursor, Parent, ClientData)) {
2348 case CXChildVisit_Break: return true;
2349 case CXChildVisit_Continue: break;
2350 case CXChildVisit_Recurse:
2351 if (PostChildrenVisitor)
2352 WL.push_back(PostChildrenVisit(0, Cursor));
2353 EnqueueWorkList(WL, S);
2354 break;
2355 }
2356 continue;
2357 }
2358 case VisitorJob::MemberExprPartsKind: {
2359 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002360 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002361
2362 // Visit the nested-name-specifier
2363 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2364 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2365 return true;
2366
2367 // Visit the declaration name.
2368 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2369 return true;
2370
2371 // Visit the explicitly-specified template arguments, if any.
2372 if (M->hasExplicitTemplateArgs()) {
2373 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2374 *ArgEnd = Arg + M->getNumTemplateArgs();
2375 Arg != ArgEnd; ++Arg) {
2376 if (VisitTemplateArgumentLoc(*Arg))
2377 return true;
2378 }
2379 }
2380 continue;
2381 }
2382 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002383 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002384 // Visit nested-name-specifier, if present.
2385 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2386 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2387 return true;
2388 // Visit declaration name.
2389 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2390 return true;
2391 continue;
2392 }
2393 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002394 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002395 // Visit the nested-name-specifier.
2396 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2397 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2398 return true;
2399 // Visit the declaration name.
2400 if (VisitDeclarationNameInfo(O->getNameInfo()))
2401 return true;
2402 // Visit the overloaded declaration reference.
2403 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2404 return true;
2405 continue;
2406 }
2407 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002408 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002409 NamedDecl *Pack = E->getPack();
2410 if (isa<TemplateTypeParmDecl>(Pack)) {
2411 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2412 E->getPackLoc(), TU)))
2413 return true;
2414
2415 continue;
2416 }
2417
2418 if (isa<TemplateTemplateParmDecl>(Pack)) {
2419 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2420 E->getPackLoc(), TU)))
2421 return true;
2422
2423 continue;
2424 }
2425
2426 // Non-type template parameter packs and function parameter packs are
2427 // treated like DeclRefExpr cursors.
2428 continue;
2429 }
2430
2431 case VisitorJob::LambdaExprPartsKind: {
2432 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002433 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002434 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2435 CEnd = E->explicit_capture_end();
2436 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002437 // FIXME: Lambda init-captures.
2438 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002440
Guy Benyei11169dd2012-12-18 14:30:41 +00002441 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2442 C->getLocation(),
2443 TU)))
2444 return true;
2445 }
2446
2447 // Visit parameters and return type, if present.
2448 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2449 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2450 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2451 // Visit the whole type.
2452 if (Visit(TL))
2453 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002454 } else if (FunctionProtoTypeLoc Proto =
2455 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002456 if (E->hasExplicitParameters()) {
2457 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002458 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2459 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002460 return true;
2461 } else {
2462 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002463 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002464 return true;
2465 }
2466 }
2467 }
2468 break;
2469 }
2470
2471 case VisitorJob::PostChildrenVisitKind:
2472 if (PostChildrenVisitor(Parent, ClientData))
2473 return true;
2474 break;
2475 }
2476 }
2477 return false;
2478}
2479
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002480bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002481 VisitorWorkList *WL = 0;
2482 if (!WorkListFreeList.empty()) {
2483 WL = WorkListFreeList.back();
2484 WL->clear();
2485 WorkListFreeList.pop_back();
2486 }
2487 else {
2488 WL = new VisitorWorkList();
2489 WorkListCache.push_back(WL);
2490 }
2491 EnqueueWorkList(*WL, S);
2492 bool result = RunVisitorWorkList(*WL);
2493 WorkListFreeList.push_back(WL);
2494 return result;
2495}
2496
2497namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002498typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002499RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2500 const DeclarationNameInfo &NI,
2501 const SourceRange &QLoc,
2502 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2503 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2504 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2505 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2506
2507 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2508
2509 RefNamePieces Pieces;
2510
2511 if (WantQualifier && QLoc.isValid())
2512 Pieces.push_back(QLoc);
2513
2514 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2515 Pieces.push_back(NI.getLoc());
2516
2517 if (WantTemplateArgs && TemplateArgs)
2518 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2519 TemplateArgs->RAngleLoc));
2520
2521 if (Kind == DeclarationName::CXXOperatorName) {
2522 Pieces.push_back(SourceLocation::getFromRawEncoding(
2523 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2524 Pieces.push_back(SourceLocation::getFromRawEncoding(
2525 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2526 }
2527
2528 if (WantSinglePiece) {
2529 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2530 Pieces.clear();
2531 Pieces.push_back(R);
2532 }
2533
2534 return Pieces;
2535}
2536}
2537
2538//===----------------------------------------------------------------------===//
2539// Misc. API hooks.
2540//===----------------------------------------------------------------------===//
2541
2542static llvm::sys::Mutex EnableMultithreadingMutex;
2543static bool EnabledMultithreading;
2544
Chad Rosier05c71aa2013-03-27 18:28:23 +00002545static void fatal_error_handler(void *user_data, const std::string& reason,
2546 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002547 // Write the result out to stderr avoiding errs() because raw_ostreams can
2548 // call report_fatal_error.
2549 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2550 ::abort();
2551}
2552
2553extern "C" {
2554CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2555 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002556 // We use crash recovery to make some of our APIs more reliable, implicitly
2557 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002558 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2559 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002560
2561 // Enable support for multithreading in LLVM.
2562 {
2563 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2564 if (!EnabledMultithreading) {
2565 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2566 llvm::llvm_start_multithreaded();
2567 EnabledMultithreading = true;
2568 }
2569 }
2570
2571 CIndexer *CIdxr = new CIndexer();
2572 if (excludeDeclarationsFromPCH)
2573 CIdxr->setOnlyLocalDecls();
2574 if (displayDiagnostics)
2575 CIdxr->setDisplayDiagnostics();
2576
2577 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2578 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2579 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2580 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2581 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2582 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2583
2584 return CIdxr;
2585}
2586
2587void clang_disposeIndex(CXIndex CIdx) {
2588 if (CIdx)
2589 delete static_cast<CIndexer *>(CIdx);
2590}
2591
2592void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2593 if (CIdx)
2594 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2595}
2596
2597unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2598 if (CIdx)
2599 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2600 return 0;
2601}
2602
2603void clang_toggleCrashRecovery(unsigned isEnabled) {
2604 if (isEnabled)
2605 llvm::CrashRecoveryContext::Enable();
2606 else
2607 llvm::CrashRecoveryContext::Disable();
2608}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002609
Guy Benyei11169dd2012-12-18 14:30:41 +00002610CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2611 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002612 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002613 enum CXErrorCode Result =
2614 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002615 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002616 assert((TU && Result == CXError_Success) ||
2617 (!TU && Result != CXError_Success));
2618 return TU;
2619}
2620
2621enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2622 const char *ast_filename,
2623 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002624 if (out_TU)
2625 *out_TU = NULL;
2626
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002627 if (!CIdx || !ast_filename || !out_TU)
2628 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002629
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002630 LOG_FUNC_SECTION {
2631 *Log << ast_filename;
2632 }
2633
Guy Benyei11169dd2012-12-18 14:30:41 +00002634 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2635 FileSystemOptions FileSystemOpts;
2636
2637 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002638 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002639 CXXIdx->getOnlyLocalDecls(), None,
2640 /*CaptureDiagnostics=*/true,
2641 /*AllowPCHWithCompilerErrors=*/true,
2642 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002643 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2644 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002645}
2646
2647unsigned clang_defaultEditingTranslationUnitOptions() {
2648 return CXTranslationUnit_PrecompiledPreamble |
2649 CXTranslationUnit_CacheCompletionResults;
2650}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002651
Guy Benyei11169dd2012-12-18 14:30:41 +00002652CXTranslationUnit
2653clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2654 const char *source_filename,
2655 int num_command_line_args,
2656 const char * const *command_line_args,
2657 unsigned num_unsaved_files,
2658 struct CXUnsavedFile *unsaved_files) {
2659 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2660 return clang_parseTranslationUnit(CIdx, source_filename,
2661 command_line_args, num_command_line_args,
2662 unsaved_files, num_unsaved_files,
2663 Options);
2664}
2665
2666struct ParseTranslationUnitInfo {
2667 CXIndex CIdx;
2668 const char *source_filename;
2669 const char *const *command_line_args;
2670 int num_command_line_args;
2671 struct CXUnsavedFile *unsaved_files;
2672 unsigned num_unsaved_files;
2673 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002674 CXTranslationUnit *out_TU;
2675 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002676};
2677static void clang_parseTranslationUnit_Impl(void *UserData) {
2678 ParseTranslationUnitInfo *PTUI =
2679 static_cast<ParseTranslationUnitInfo*>(UserData);
2680 CXIndex CIdx = PTUI->CIdx;
2681 const char *source_filename = PTUI->source_filename;
2682 const char * const *command_line_args = PTUI->command_line_args;
2683 int num_command_line_args = PTUI->num_command_line_args;
2684 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2685 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2686 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002687 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002688
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002689 // Set up the initial return values.
2690 if (out_TU)
2691 *out_TU = NULL;
2692 PTUI->result = CXError_Failure;
2693
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002694 // Check arguments.
2695 if (!CIdx || !out_TU ||
2696 (unsaved_files == NULL && num_unsaved_files != 0)) {
2697 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002698 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002699 }
2700
Guy Benyei11169dd2012-12-18 14:30:41 +00002701 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2702
2703 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2704 setThreadBackgroundPriority();
2705
2706 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2707 // FIXME: Add a flag for modules.
2708 TranslationUnitKind TUKind
2709 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002710 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002711 = options & CXTranslationUnit_CacheCompletionResults;
2712 bool IncludeBriefCommentsInCodeCompletion
2713 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2714 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2715 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2716
2717 // Configure the diagnostics.
2718 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002719 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002720
2721 // Recover resources if we crash before exiting this function.
2722 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2723 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2724 DiagCleanup(Diags.getPtr());
2725
Ahmed Charlesb8984322014-03-07 20:03:18 +00002726 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2727 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002728
2729 // Recover resources if we crash before exiting this function.
2730 llvm::CrashRecoveryContextCleanupRegistrar<
2731 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2732
2733 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2734 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2735 const llvm::MemoryBuffer *Buffer
2736 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2737 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2738 Buffer));
2739 }
2740
Ahmed Charlesb8984322014-03-07 20:03:18 +00002741 std::unique_ptr<std::vector<const char *>> Args(
2742 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002743
2744 // Recover resources if we crash before exiting this method.
2745 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2746 ArgsCleanup(Args.get());
2747
2748 // Since the Clang C library is primarily used by batch tools dealing with
2749 // (often very broken) source code, where spell-checking can have a
2750 // significant negative impact on performance (particularly when
2751 // precompiled headers are involved), we disable it by default.
2752 // Only do this if we haven't found a spell-checking-related argument.
2753 bool FoundSpellCheckingArgument = false;
2754 for (int I = 0; I != num_command_line_args; ++I) {
2755 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2756 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2757 FoundSpellCheckingArgument = true;
2758 break;
2759 }
2760 }
2761 if (!FoundSpellCheckingArgument)
2762 Args->push_back("-fno-spell-checking");
2763
2764 Args->insert(Args->end(), command_line_args,
2765 command_line_args + num_command_line_args);
2766
2767 // The 'source_filename' argument is optional. If the caller does not
2768 // specify it then it is assumed that the source file is specified
2769 // in the actual argument list.
2770 // Put the source file after command_line_args otherwise if '-x' flag is
2771 // present it will be unused.
2772 if (source_filename)
2773 Args->push_back(source_filename);
2774
2775 // Do we need the detailed preprocessing record?
2776 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2777 Args->push_back("-Xclang");
2778 Args->push_back("-detailed-preprocessing-record");
2779 }
2780
2781 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002782 std::unique_ptr<ASTUnit> ErrUnit;
2783 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002784 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002785 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2786 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2787 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2788 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2789 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2790 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002791
2792 if (NumErrors != Diags->getClient()->getNumErrors()) {
2793 // Make sure to check that 'Unit' is non-NULL.
2794 if (CXXIdx->getDisplayDiagnostics())
2795 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2796 }
2797
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002798 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2799 PTUI->result = CXError_ASTReadError;
2800 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002801 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002802 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2803 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002804}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002805
2806CXTranslationUnit
2807clang_parseTranslationUnit(CXIndex CIdx,
2808 const char *source_filename,
2809 const char *const *command_line_args,
2810 int num_command_line_args,
2811 struct CXUnsavedFile *unsaved_files,
2812 unsigned num_unsaved_files,
2813 unsigned options) {
2814 CXTranslationUnit TU;
2815 enum CXErrorCode Result = clang_parseTranslationUnit2(
2816 CIdx, source_filename, command_line_args, num_command_line_args,
2817 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002818 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002819 assert((TU && Result == CXError_Success) ||
2820 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002821 return TU;
2822}
2823
2824enum CXErrorCode clang_parseTranslationUnit2(
2825 CXIndex CIdx,
2826 const char *source_filename,
2827 const char *const *command_line_args,
2828 int num_command_line_args,
2829 struct CXUnsavedFile *unsaved_files,
2830 unsigned num_unsaved_files,
2831 unsigned options,
2832 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002833 LOG_FUNC_SECTION {
2834 *Log << source_filename << ": ";
2835 for (int i = 0; i != num_command_line_args; ++i)
2836 *Log << command_line_args[i] << " ";
2837 }
2838
Guy Benyei11169dd2012-12-18 14:30:41 +00002839 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2840 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002841 num_unsaved_files, options, out_TU,
2842 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002843 llvm::CrashRecoveryContext CRC;
2844
2845 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2846 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2847 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2848 fprintf(stderr, " 'command_line_args' : [");
2849 for (int i = 0; i != num_command_line_args; ++i) {
2850 if (i)
2851 fprintf(stderr, ", ");
2852 fprintf(stderr, "'%s'", command_line_args[i]);
2853 }
2854 fprintf(stderr, "],\n");
2855 fprintf(stderr, " 'unsaved_files' : [");
2856 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2857 if (i)
2858 fprintf(stderr, ", ");
2859 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2860 unsaved_files[i].Length);
2861 }
2862 fprintf(stderr, "],\n");
2863 fprintf(stderr, " 'options' : %d,\n", options);
2864 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002865
2866 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002867 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002868 if (CXTranslationUnit *TU = PTUI.out_TU)
2869 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002870 }
2871
2872 return PTUI.result;
2873}
2874
2875unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2876 return CXSaveTranslationUnit_None;
2877}
2878
2879namespace {
2880
2881struct SaveTranslationUnitInfo {
2882 CXTranslationUnit TU;
2883 const char *FileName;
2884 unsigned options;
2885 CXSaveError result;
2886};
2887
2888}
2889
2890static void clang_saveTranslationUnit_Impl(void *UserData) {
2891 SaveTranslationUnitInfo *STUI =
2892 static_cast<SaveTranslationUnitInfo*>(UserData);
2893
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002894 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002895 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2896 setThreadBackgroundPriority();
2897
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002898 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002899 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2900}
2901
2902int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2903 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002904 LOG_FUNC_SECTION {
2905 *Log << TU << ' ' << FileName;
2906 }
2907
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002908 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002909 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002910 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002911 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002912
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002913 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002914 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2915 if (!CXXUnit->hasSema())
2916 return CXSaveError_InvalidTU;
2917
2918 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2919
2920 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2921 getenv("LIBCLANG_NOTHREADS")) {
2922 clang_saveTranslationUnit_Impl(&STUI);
2923
2924 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2925 PrintLibclangResourceUsage(TU);
2926
2927 return STUI.result;
2928 }
2929
2930 // We have an AST that has invalid nodes due to compiler errors.
2931 // Use a crash recovery thread for protection.
2932
2933 llvm::CrashRecoveryContext CRC;
2934
2935 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2936 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2937 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2938 fprintf(stderr, " 'options' : %d,\n", options);
2939 fprintf(stderr, "}\n");
2940
2941 return CXSaveError_Unknown;
2942
2943 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2944 PrintLibclangResourceUsage(TU);
2945 }
2946
2947 return STUI.result;
2948}
2949
2950void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2951 if (CTUnit) {
2952 // If the translation unit has been marked as unsafe to free, just discard
2953 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002954 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2955 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002956 return;
2957
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002958 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002959 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002960 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2961 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002962 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002963 delete CTUnit;
2964 }
2965}
2966
2967unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2968 return CXReparse_None;
2969}
2970
2971struct ReparseTranslationUnitInfo {
2972 CXTranslationUnit TU;
2973 unsigned num_unsaved_files;
2974 struct CXUnsavedFile *unsaved_files;
2975 unsigned options;
2976 int result;
2977};
2978
2979static void clang_reparseTranslationUnit_Impl(void *UserData) {
2980 ReparseTranslationUnitInfo *RTUI =
2981 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002982 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002983
Guy Benyei11169dd2012-12-18 14:30:41 +00002984 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002985 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2986 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2987 unsigned options = RTUI->options;
2988 (void) options;
2989
2990 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002991 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002992 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002993 RTUI->result = CXError_InvalidArguments;
2994 return;
2995 }
2996 if (unsaved_files == NULL && num_unsaved_files != 0) {
2997 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00002998 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002999 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003000
3001 // Reset the associated diagnostics.
3002 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3003 TU->Diagnostics = 0;
3004
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003005 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003006 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3007 setThreadBackgroundPriority();
3008
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003009 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003010 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003011
3012 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3013 new std::vector<ASTUnit::RemappedFile>());
3014
Guy Benyei11169dd2012-12-18 14:30:41 +00003015 // Recover resources if we crash before exiting this function.
3016 llvm::CrashRecoveryContextCleanupRegistrar<
3017 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3018
3019 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3020 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3021 const llvm::MemoryBuffer *Buffer
3022 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3023 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3024 Buffer));
3025 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003026
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003027 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003028 RTUI->result = CXError_Success;
3029 else if (isASTReadError(CXXUnit))
3030 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003031}
3032
3033int clang_reparseTranslationUnit(CXTranslationUnit TU,
3034 unsigned num_unsaved_files,
3035 struct CXUnsavedFile *unsaved_files,
3036 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003037 LOG_FUNC_SECTION {
3038 *Log << TU;
3039 }
3040
Guy Benyei11169dd2012-12-18 14:30:41 +00003041 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003042 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003043
3044 if (getenv("LIBCLANG_NOTHREADS")) {
3045 clang_reparseTranslationUnit_Impl(&RTUI);
3046 return RTUI.result;
3047 }
3048
3049 llvm::CrashRecoveryContext CRC;
3050
3051 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3052 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003053 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003054 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003055 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3056 PrintLibclangResourceUsage(TU);
3057
3058 return RTUI.result;
3059}
3060
3061
3062CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003063 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003064 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003065 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003066 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003067
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003068 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003069 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003070}
3071
3072CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003073 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003074 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003075 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003076 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003077
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003078 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003079 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3080}
3081
3082} // end: extern "C"
3083
3084//===----------------------------------------------------------------------===//
3085// CXFile Operations.
3086//===----------------------------------------------------------------------===//
3087
3088extern "C" {
3089CXString clang_getFileName(CXFile SFile) {
3090 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003091 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003092
3093 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003094 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003095}
3096
3097time_t clang_getFileTime(CXFile SFile) {
3098 if (!SFile)
3099 return 0;
3100
3101 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3102 return FEnt->getModificationTime();
3103}
3104
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003105CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003106 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003107 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003108 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003109 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003110
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003111 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003112
3113 FileManager &FMgr = CXXUnit->getFileManager();
3114 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3115}
3116
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003117unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3118 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003119 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003120 LOG_BAD_TU(TU);
3121 return 0;
3122 }
3123
3124 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003125 return 0;
3126
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003127 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003128 FileEntry *FEnt = static_cast<FileEntry *>(file);
3129 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3130 .isFileMultipleIncludeGuarded(FEnt);
3131}
3132
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003133int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3134 if (!file || !outID)
3135 return 1;
3136
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003137 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003138 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3139 outID->data[0] = ID.getDevice();
3140 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003141 outID->data[2] = FEnt->getModificationTime();
3142 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003143}
3144
Guy Benyei11169dd2012-12-18 14:30:41 +00003145} // end: extern "C"
3146
3147//===----------------------------------------------------------------------===//
3148// CXCursor Operations.
3149//===----------------------------------------------------------------------===//
3150
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003151static const Decl *getDeclFromExpr(const Stmt *E) {
3152 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003153 return getDeclFromExpr(CE->getSubExpr());
3154
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003155 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003156 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003157 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003158 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003159 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003160 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003161 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003162 if (PRE->isExplicitProperty())
3163 return PRE->getExplicitProperty();
3164 // It could be messaging both getter and setter as in:
3165 // ++myobj.myprop;
3166 // in which case prefer to associate the setter since it is less obvious
3167 // from inspecting the source that the setter is going to get called.
3168 if (PRE->isMessagingSetter())
3169 return PRE->getImplicitPropertySetter();
3170 return PRE->getImplicitPropertyGetter();
3171 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003172 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003173 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003174 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003175 if (Expr *Src = OVE->getSourceExpr())
3176 return getDeclFromExpr(Src);
3177
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003178 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003179 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003180 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003181 if (!CE->isElidable())
3182 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003183 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003184 return OME->getMethodDecl();
3185
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003186 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003187 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003188 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003189 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3190 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003191 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003192 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3193 isa<ParmVarDecl>(SizeOfPack->getPack()))
3194 return SizeOfPack->getPack();
3195
3196 return 0;
3197}
3198
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003199static SourceLocation getLocationFromExpr(const Expr *E) {
3200 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003201 return getLocationFromExpr(CE->getSubExpr());
3202
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003203 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003204 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003205 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003206 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003207 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003208 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003209 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003210 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003211 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003212 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003213 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003214 return PropRef->getLocation();
3215
3216 return E->getLocStart();
3217}
3218
3219extern "C" {
3220
3221unsigned clang_visitChildren(CXCursor parent,
3222 CXCursorVisitor visitor,
3223 CXClientData client_data) {
3224 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3225 /*VisitPreprocessorLast=*/false);
3226 return CursorVis.VisitChildren(parent);
3227}
3228
3229#ifndef __has_feature
3230#define __has_feature(x) 0
3231#endif
3232#if __has_feature(blocks)
3233typedef enum CXChildVisitResult
3234 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3235
3236static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3237 CXClientData client_data) {
3238 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3239 return block(cursor, parent);
3240}
3241#else
3242// If we are compiled with a compiler that doesn't have native blocks support,
3243// define and call the block manually, so the
3244typedef struct _CXChildVisitResult
3245{
3246 void *isa;
3247 int flags;
3248 int reserved;
3249 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3250 CXCursor);
3251} *CXCursorVisitorBlock;
3252
3253static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3254 CXClientData client_data) {
3255 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3256 return block->invoke(block, cursor, parent);
3257}
3258#endif
3259
3260
3261unsigned clang_visitChildrenWithBlock(CXCursor parent,
3262 CXCursorVisitorBlock block) {
3263 return clang_visitChildren(parent, visitWithBlock, block);
3264}
3265
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003266static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003267 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003268 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003269
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003270 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003271 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003272 if (const ObjCPropertyImplDecl *PropImpl =
3273 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003274 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003275 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003276
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003277 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003278 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003279 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003280
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003281 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003282 }
3283
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003284 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003285 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003286
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003287 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003288 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3289 // and returns different names. NamedDecl returns the class name and
3290 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003291 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003292
3293 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003294 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003295
3296 SmallString<1024> S;
3297 llvm::raw_svector_ostream os(S);
3298 ND->printName(os);
3299
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003300 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003301}
3302
3303CXString clang_getCursorSpelling(CXCursor C) {
3304 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003305 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003306
3307 if (clang_isReference(C.kind)) {
3308 switch (C.kind) {
3309 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003310 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003311 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003312 }
3313 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003314 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003315 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003316 }
3317 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003318 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003319 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003320 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003321 }
3322 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003323 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003324 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003325 }
3326 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003327 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003328 assert(Type && "Missing type decl");
3329
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003330 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003331 getAsString());
3332 }
3333 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003334 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003335 assert(Template && "Missing template decl");
3336
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003337 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 }
3339
3340 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003341 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003342 assert(NS && "Missing namespace decl");
3343
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003344 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003345 }
3346
3347 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003348 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 assert(Field && "Missing member decl");
3350
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003351 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003352 }
3353
3354 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003355 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003356 assert(Label && "Missing label");
3357
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003358 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003359 }
3360
3361 case CXCursor_OverloadedDeclRef: {
3362 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003363 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3364 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003365 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003366 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003367 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003368 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003369 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003370 OverloadedTemplateStorage *Ovl
3371 = Storage.get<OverloadedTemplateStorage*>();
3372 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003373 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003374 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003375 }
3376
3377 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003378 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003379 assert(Var && "Missing variable decl");
3380
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003381 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003382 }
3383
3384 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003385 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003386 }
3387 }
3388
3389 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003390 const Expr *E = getCursorExpr(C);
3391
3392 if (C.kind == CXCursor_ObjCStringLiteral ||
3393 C.kind == CXCursor_StringLiteral) {
3394 const StringLiteral *SLit;
3395 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3396 SLit = OSL->getString();
3397 } else {
3398 SLit = cast<StringLiteral>(E);
3399 }
3400 SmallString<256> Buf;
3401 llvm::raw_svector_ostream OS(Buf);
3402 SLit->outputString(OS);
3403 return cxstring::createDup(OS.str());
3404 }
3405
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003406 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003407 if (D)
3408 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003409 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003410 }
3411
3412 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003413 const Stmt *S = getCursorStmt(C);
3414 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003415 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003416
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003417 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003418 }
3419
3420 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003421 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003422 ->getNameStart());
3423
3424 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003425 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003426 ->getNameStart());
3427
3428 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003429 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003430
3431 if (clang_isDeclaration(C.kind))
3432 return getDeclSpelling(getCursorDecl(C));
3433
3434 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003435 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003436 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003437 }
3438
3439 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003440 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003441 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003442 }
3443
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003444 if (C.kind == CXCursor_PackedAttr) {
3445 return cxstring::createRef("packed");
3446 }
3447
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003448 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003449}
3450
3451CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3452 unsigned pieceIndex,
3453 unsigned options) {
3454 if (clang_Cursor_isNull(C))
3455 return clang_getNullRange();
3456
3457 ASTContext &Ctx = getCursorContext(C);
3458
3459 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003460 const Stmt *S = getCursorStmt(C);
3461 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003462 if (pieceIndex > 0)
3463 return clang_getNullRange();
3464 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3465 }
3466
3467 return clang_getNullRange();
3468 }
3469
3470 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003471 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003472 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3473 if (pieceIndex >= ME->getNumSelectorLocs())
3474 return clang_getNullRange();
3475 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3476 }
3477 }
3478
3479 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3480 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003481 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003482 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3483 if (pieceIndex >= MD->getNumSelectorLocs())
3484 return clang_getNullRange();
3485 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3486 }
3487 }
3488
3489 if (C.kind == CXCursor_ObjCCategoryDecl ||
3490 C.kind == CXCursor_ObjCCategoryImplDecl) {
3491 if (pieceIndex > 0)
3492 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003493 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003494 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3495 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003496 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003497 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3498 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3499 }
3500
3501 if (C.kind == CXCursor_ModuleImportDecl) {
3502 if (pieceIndex > 0)
3503 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003504 if (const ImportDecl *ImportD =
3505 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003506 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3507 if (!Locs.empty())
3508 return cxloc::translateSourceRange(Ctx,
3509 SourceRange(Locs.front(), Locs.back()));
3510 }
3511 return clang_getNullRange();
3512 }
3513
3514 // FIXME: A CXCursor_InclusionDirective should give the location of the
3515 // filename, but we don't keep track of this.
3516
3517 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3518 // but we don't keep track of this.
3519
3520 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3521 // but we don't keep track of this.
3522
3523 // Default handling, give the location of the cursor.
3524
3525 if (pieceIndex > 0)
3526 return clang_getNullRange();
3527
3528 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3529 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3530 return cxloc::translateSourceRange(Ctx, Loc);
3531}
3532
3533CXString clang_getCursorDisplayName(CXCursor C) {
3534 if (!clang_isDeclaration(C.kind))
3535 return clang_getCursorSpelling(C);
3536
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003537 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003538 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003539 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003540
3541 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003542 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 D = FunTmpl->getTemplatedDecl();
3544
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003545 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003546 SmallString<64> Str;
3547 llvm::raw_svector_ostream OS(Str);
3548 OS << *Function;
3549 if (Function->getPrimaryTemplate())
3550 OS << "<>";
3551 OS << "(";
3552 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3553 if (I)
3554 OS << ", ";
3555 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3556 }
3557
3558 if (Function->isVariadic()) {
3559 if (Function->getNumParams())
3560 OS << ", ";
3561 OS << "...";
3562 }
3563 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003564 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003565 }
3566
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003567 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003568 SmallString<64> Str;
3569 llvm::raw_svector_ostream OS(Str);
3570 OS << *ClassTemplate;
3571 OS << "<";
3572 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3573 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3574 if (I)
3575 OS << ", ";
3576
3577 NamedDecl *Param = Params->getParam(I);
3578 if (Param->getIdentifier()) {
3579 OS << Param->getIdentifier()->getName();
3580 continue;
3581 }
3582
3583 // There is no parameter name, which makes this tricky. Try to come up
3584 // with something useful that isn't too long.
3585 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3586 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3587 else if (NonTypeTemplateParmDecl *NTTP
3588 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3589 OS << NTTP->getType().getAsString(Policy);
3590 else
3591 OS << "template<...> class";
3592 }
3593
3594 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003595 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003596 }
3597
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003598 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3600 // If the type was explicitly written, use that.
3601 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003602 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003603
Benjamin Kramer9170e912013-02-22 15:46:01 +00003604 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003605 llvm::raw_svector_ostream OS(Str);
3606 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003607 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003608 ClassSpec->getTemplateArgs().data(),
3609 ClassSpec->getTemplateArgs().size(),
3610 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003611 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003612 }
3613
3614 return clang_getCursorSpelling(C);
3615}
3616
3617CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3618 switch (Kind) {
3619 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003620 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003621 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003622 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003624 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003626 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003628 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003630 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003632 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003633 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003634 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003636 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003638 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003639 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003640 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003642 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003643 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003644 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003646 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003648 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003650 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003652 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003654 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003656 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003658 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003660 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003662 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003664 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003666 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003668 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003670 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003672 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003747 case CXCursor_ObjCSelfExpr:
3748 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003865 case CXCursor_PackedAttr:
3866 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003910 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003914 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003915 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003916 return cxstring::createRef("OMPParallelDirective");
3917 case CXCursor_OMPSimdDirective:
3918 return cxstring::createRef("OMPSimdDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 }
3920
3921 llvm_unreachable("Unhandled CXCursorKind");
3922}
3923
3924struct GetCursorData {
3925 SourceLocation TokenBeginLoc;
3926 bool PointsAtMacroArgExpansion;
3927 bool VisitedObjCPropertyImplDecl;
3928 SourceLocation VisitedDeclaratorDeclStartLoc;
3929 CXCursor &BestCursor;
3930
3931 GetCursorData(SourceManager &SM,
3932 SourceLocation tokenBegin, CXCursor &outputCursor)
3933 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3934 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3935 VisitedObjCPropertyImplDecl = false;
3936 }
3937};
3938
3939static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3940 CXCursor parent,
3941 CXClientData client_data) {
3942 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3943 CXCursor *BestCursor = &Data->BestCursor;
3944
3945 // If we point inside a macro argument we should provide info of what the
3946 // token is so use the actual cursor, don't replace it with a macro expansion
3947 // cursor.
3948 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3949 return CXChildVisit_Recurse;
3950
3951 if (clang_isDeclaration(cursor.kind)) {
3952 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003953 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003954 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3955 if (MD->isImplicit())
3956 return CXChildVisit_Break;
3957
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003958 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003959 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3960 // Check that when we have multiple @class references in the same line,
3961 // that later ones do not override the previous ones.
3962 // If we have:
3963 // @class Foo, Bar;
3964 // source ranges for both start at '@', so 'Bar' will end up overriding
3965 // 'Foo' even though the cursor location was at 'Foo'.
3966 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3967 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003968 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3970 if (PrevID != ID &&
3971 !PrevID->isThisDeclarationADefinition() &&
3972 !ID->isThisDeclarationADefinition())
3973 return CXChildVisit_Break;
3974 }
3975
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003976 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003977 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3978 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3979 // Check that when we have multiple declarators in the same line,
3980 // that later ones do not override the previous ones.
3981 // If we have:
3982 // int Foo, Bar;
3983 // source ranges for both start at 'int', so 'Bar' will end up overriding
3984 // 'Foo' even though the cursor location was at 'Foo'.
3985 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3986 return CXChildVisit_Break;
3987 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3988
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003989 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3991 (void)PropImp;
3992 // Check that when we have multiple @synthesize in the same line,
3993 // that later ones do not override the previous ones.
3994 // If we have:
3995 // @synthesize Foo, Bar;
3996 // source ranges for both start at '@', so 'Bar' will end up overriding
3997 // 'Foo' even though the cursor location was at 'Foo'.
3998 if (Data->VisitedObjCPropertyImplDecl)
3999 return CXChildVisit_Break;
4000 Data->VisitedObjCPropertyImplDecl = true;
4001 }
4002 }
4003
4004 if (clang_isExpression(cursor.kind) &&
4005 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004006 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004007 // Avoid having the cursor of an expression replace the declaration cursor
4008 // when the expression source range overlaps the declaration range.
4009 // This can happen for C++ constructor expressions whose range generally
4010 // include the variable declaration, e.g.:
4011 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4012 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4013 D->getLocation() == Data->TokenBeginLoc)
4014 return CXChildVisit_Break;
4015 }
4016 }
4017
4018 // If our current best cursor is the construction of a temporary object,
4019 // don't replace that cursor with a type reference, because we want
4020 // clang_getCursor() to point at the constructor.
4021 if (clang_isExpression(BestCursor->kind) &&
4022 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4023 cursor.kind == CXCursor_TypeRef) {
4024 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4025 // as having the actual point on the type reference.
4026 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4027 return CXChildVisit_Recurse;
4028 }
4029
4030 *BestCursor = cursor;
4031 return CXChildVisit_Recurse;
4032}
4033
4034CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004035 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004036 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004038 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004039
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004040 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4042
4043 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4044 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4045
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004046 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004047 CXFile SearchFile;
4048 unsigned SearchLine, SearchColumn;
4049 CXFile ResultFile;
4050 unsigned ResultLine, ResultColumn;
4051 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4052 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4053 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4054
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004055 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4056 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004057 &ResultColumn, 0);
4058 SearchFileName = clang_getFileName(SearchFile);
4059 ResultFileName = clang_getFileName(ResultFile);
4060 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4061 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004062 *Log << llvm::format("(%s:%d:%d) = %s",
4063 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4064 clang_getCString(KindSpelling))
4065 << llvm::format("(%s:%d:%d):%s%s",
4066 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4067 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 clang_disposeString(SearchFileName);
4069 clang_disposeString(ResultFileName);
4070 clang_disposeString(KindSpelling);
4071 clang_disposeString(USR);
4072
4073 CXCursor Definition = clang_getCursorDefinition(Result);
4074 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4075 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4076 CXString DefinitionKindSpelling
4077 = clang_getCursorKindSpelling(Definition.kind);
4078 CXFile DefinitionFile;
4079 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004080 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 &DefinitionLine, &DefinitionColumn, 0);
4082 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004083 *Log << llvm::format(" -> %s(%s:%d:%d)",
4084 clang_getCString(DefinitionKindSpelling),
4085 clang_getCString(DefinitionFileName),
4086 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004087 clang_disposeString(DefinitionFileName);
4088 clang_disposeString(DefinitionKindSpelling);
4089 }
4090 }
4091
4092 return Result;
4093}
4094
4095CXCursor clang_getNullCursor(void) {
4096 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4097}
4098
4099unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004100 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4101 // can't set consistently. For example, when visiting a DeclStmt we will set
4102 // it but we don't set it on the result of clang_getCursorDefinition for
4103 // a reference of the same declaration.
4104 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4105 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4106 // to provide that kind of info.
4107 if (clang_isDeclaration(X.kind))
4108 X.data[1] = 0;
4109 if (clang_isDeclaration(Y.kind))
4110 Y.data[1] = 0;
4111
Guy Benyei11169dd2012-12-18 14:30:41 +00004112 return X == Y;
4113}
4114
4115unsigned clang_hashCursor(CXCursor C) {
4116 unsigned Index = 0;
4117 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4118 Index = 1;
4119
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004120 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 std::make_pair(C.kind, C.data[Index]));
4122}
4123
4124unsigned clang_isInvalid(enum CXCursorKind K) {
4125 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4126}
4127
4128unsigned clang_isDeclaration(enum CXCursorKind K) {
4129 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4130 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4131}
4132
4133unsigned clang_isReference(enum CXCursorKind K) {
4134 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4135}
4136
4137unsigned clang_isExpression(enum CXCursorKind K) {
4138 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4139}
4140
4141unsigned clang_isStatement(enum CXCursorKind K) {
4142 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4143}
4144
4145unsigned clang_isAttribute(enum CXCursorKind K) {
4146 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4147}
4148
4149unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4150 return K == CXCursor_TranslationUnit;
4151}
4152
4153unsigned clang_isPreprocessing(enum CXCursorKind K) {
4154 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4155}
4156
4157unsigned clang_isUnexposed(enum CXCursorKind K) {
4158 switch (K) {
4159 case CXCursor_UnexposedDecl:
4160 case CXCursor_UnexposedExpr:
4161 case CXCursor_UnexposedStmt:
4162 case CXCursor_UnexposedAttr:
4163 return true;
4164 default:
4165 return false;
4166 }
4167}
4168
4169CXCursorKind clang_getCursorKind(CXCursor C) {
4170 return C.kind;
4171}
4172
4173CXSourceLocation clang_getCursorLocation(CXCursor C) {
4174 if (clang_isReference(C.kind)) {
4175 switch (C.kind) {
4176 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004177 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004178 = getCursorObjCSuperClassRef(C);
4179 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4180 }
4181
4182 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004183 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004184 = getCursorObjCProtocolRef(C);
4185 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4186 }
4187
4188 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004189 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004190 = getCursorObjCClassRef(C);
4191 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4192 }
4193
4194 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004195 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004196 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4197 }
4198
4199 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004200 std::pair<const TemplateDecl *, SourceLocation> P =
4201 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004202 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4203 }
4204
4205 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004206 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4208 }
4209
4210 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004211 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004212 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4213 }
4214
4215 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004216 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004217 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4218 }
4219
4220 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004221 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 if (!BaseSpec)
4223 return clang_getNullLocation();
4224
4225 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4226 return cxloc::translateSourceLocation(getCursorContext(C),
4227 TSInfo->getTypeLoc().getBeginLoc());
4228
4229 return cxloc::translateSourceLocation(getCursorContext(C),
4230 BaseSpec->getLocStart());
4231 }
4232
4233 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004234 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004235 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4236 }
4237
4238 case CXCursor_OverloadedDeclRef:
4239 return cxloc::translateSourceLocation(getCursorContext(C),
4240 getCursorOverloadedDeclRef(C).second);
4241
4242 default:
4243 // FIXME: Need a way to enumerate all non-reference cases.
4244 llvm_unreachable("Missed a reference kind");
4245 }
4246 }
4247
4248 if (clang_isExpression(C.kind))
4249 return cxloc::translateSourceLocation(getCursorContext(C),
4250 getLocationFromExpr(getCursorExpr(C)));
4251
4252 if (clang_isStatement(C.kind))
4253 return cxloc::translateSourceLocation(getCursorContext(C),
4254 getCursorStmt(C)->getLocStart());
4255
4256 if (C.kind == CXCursor_PreprocessingDirective) {
4257 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4258 return cxloc::translateSourceLocation(getCursorContext(C), L);
4259 }
4260
4261 if (C.kind == CXCursor_MacroExpansion) {
4262 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004263 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004264 return cxloc::translateSourceLocation(getCursorContext(C), L);
4265 }
4266
4267 if (C.kind == CXCursor_MacroDefinition) {
4268 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4269 return cxloc::translateSourceLocation(getCursorContext(C), L);
4270 }
4271
4272 if (C.kind == CXCursor_InclusionDirective) {
4273 SourceLocation L
4274 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4275 return cxloc::translateSourceLocation(getCursorContext(C), L);
4276 }
4277
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004278 if (clang_isAttribute(C.kind)) {
4279 SourceLocation L
4280 = cxcursor::getCursorAttr(C)->getLocation();
4281 return cxloc::translateSourceLocation(getCursorContext(C), L);
4282 }
4283
Guy Benyei11169dd2012-12-18 14:30:41 +00004284 if (!clang_isDeclaration(C.kind))
4285 return clang_getNullLocation();
4286
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004287 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004288 if (!D)
4289 return clang_getNullLocation();
4290
4291 SourceLocation Loc = D->getLocation();
4292 // FIXME: Multiple variables declared in a single declaration
4293 // currently lack the information needed to correctly determine their
4294 // ranges when accounting for the type-specifier. We use context
4295 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4296 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004297 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004298 if (!cxcursor::isFirstInDeclGroup(C))
4299 Loc = VD->getLocation();
4300 }
4301
4302 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004303 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004304 Loc = MD->getSelectorStartLoc();
4305
4306 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4307}
4308
4309} // end extern "C"
4310
4311CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4312 assert(TU);
4313
4314 // Guard against an invalid SourceLocation, or we may assert in one
4315 // of the following calls.
4316 if (SLoc.isInvalid())
4317 return clang_getNullCursor();
4318
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004319 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004320
4321 // Translate the given source location to make it point at the beginning of
4322 // the token under the cursor.
4323 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4324 CXXUnit->getASTContext().getLangOpts());
4325
4326 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4327 if (SLoc.isValid()) {
4328 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4329 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4330 /*VisitPreprocessorLast=*/true,
4331 /*VisitIncludedEntities=*/false,
4332 SourceLocation(SLoc));
4333 CursorVis.visitFileRegion();
4334 }
4335
4336 return Result;
4337}
4338
4339static SourceRange getRawCursorExtent(CXCursor C) {
4340 if (clang_isReference(C.kind)) {
4341 switch (C.kind) {
4342 case CXCursor_ObjCSuperClassRef:
4343 return getCursorObjCSuperClassRef(C).second;
4344
4345 case CXCursor_ObjCProtocolRef:
4346 return getCursorObjCProtocolRef(C).second;
4347
4348 case CXCursor_ObjCClassRef:
4349 return getCursorObjCClassRef(C).second;
4350
4351 case CXCursor_TypeRef:
4352 return getCursorTypeRef(C).second;
4353
4354 case CXCursor_TemplateRef:
4355 return getCursorTemplateRef(C).second;
4356
4357 case CXCursor_NamespaceRef:
4358 return getCursorNamespaceRef(C).second;
4359
4360 case CXCursor_MemberRef:
4361 return getCursorMemberRef(C).second;
4362
4363 case CXCursor_CXXBaseSpecifier:
4364 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4365
4366 case CXCursor_LabelRef:
4367 return getCursorLabelRef(C).second;
4368
4369 case CXCursor_OverloadedDeclRef:
4370 return getCursorOverloadedDeclRef(C).second;
4371
4372 case CXCursor_VariableRef:
4373 return getCursorVariableRef(C).second;
4374
4375 default:
4376 // FIXME: Need a way to enumerate all non-reference cases.
4377 llvm_unreachable("Missed a reference kind");
4378 }
4379 }
4380
4381 if (clang_isExpression(C.kind))
4382 return getCursorExpr(C)->getSourceRange();
4383
4384 if (clang_isStatement(C.kind))
4385 return getCursorStmt(C)->getSourceRange();
4386
4387 if (clang_isAttribute(C.kind))
4388 return getCursorAttr(C)->getRange();
4389
4390 if (C.kind == CXCursor_PreprocessingDirective)
4391 return cxcursor::getCursorPreprocessingDirective(C);
4392
4393 if (C.kind == CXCursor_MacroExpansion) {
4394 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004395 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004396 return TU->mapRangeFromPreamble(Range);
4397 }
4398
4399 if (C.kind == CXCursor_MacroDefinition) {
4400 ASTUnit *TU = getCursorASTUnit(C);
4401 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4402 return TU->mapRangeFromPreamble(Range);
4403 }
4404
4405 if (C.kind == CXCursor_InclusionDirective) {
4406 ASTUnit *TU = getCursorASTUnit(C);
4407 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4408 return TU->mapRangeFromPreamble(Range);
4409 }
4410
4411 if (C.kind == CXCursor_TranslationUnit) {
4412 ASTUnit *TU = getCursorASTUnit(C);
4413 FileID MainID = TU->getSourceManager().getMainFileID();
4414 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4415 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4416 return SourceRange(Start, End);
4417 }
4418
4419 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004420 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004421 if (!D)
4422 return SourceRange();
4423
4424 SourceRange R = D->getSourceRange();
4425 // FIXME: Multiple variables declared in a single declaration
4426 // currently lack the information needed to correctly determine their
4427 // ranges when accounting for the type-specifier. We use context
4428 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4429 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004430 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004431 if (!cxcursor::isFirstInDeclGroup(C))
4432 R.setBegin(VD->getLocation());
4433 }
4434 return R;
4435 }
4436 return SourceRange();
4437}
4438
4439/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4440/// the decl-specifier-seq for declarations.
4441static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4442 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004443 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004444 if (!D)
4445 return SourceRange();
4446
4447 SourceRange R = D->getSourceRange();
4448
4449 // Adjust the start of the location for declarations preceded by
4450 // declaration specifiers.
4451 SourceLocation StartLoc;
4452 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4453 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4454 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004455 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004456 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4457 StartLoc = TI->getTypeLoc().getLocStart();
4458 }
4459
4460 if (StartLoc.isValid() && R.getBegin().isValid() &&
4461 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4462 R.setBegin(StartLoc);
4463
4464 // FIXME: Multiple variables declared in a single declaration
4465 // currently lack the information needed to correctly determine their
4466 // ranges when accounting for the type-specifier. We use context
4467 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4468 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004469 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004470 if (!cxcursor::isFirstInDeclGroup(C))
4471 R.setBegin(VD->getLocation());
4472 }
4473
4474 return R;
4475 }
4476
4477 return getRawCursorExtent(C);
4478}
4479
4480extern "C" {
4481
4482CXSourceRange clang_getCursorExtent(CXCursor C) {
4483 SourceRange R = getRawCursorExtent(C);
4484 if (R.isInvalid())
4485 return clang_getNullRange();
4486
4487 return cxloc::translateSourceRange(getCursorContext(C), R);
4488}
4489
4490CXCursor clang_getCursorReferenced(CXCursor C) {
4491 if (clang_isInvalid(C.kind))
4492 return clang_getNullCursor();
4493
4494 CXTranslationUnit tu = getCursorTU(C);
4495 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004496 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004497 if (!D)
4498 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004499 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004500 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004501 if (const ObjCPropertyImplDecl *PropImpl =
4502 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004503 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4504 return MakeCXCursor(Property, tu);
4505
4506 return C;
4507 }
4508
4509 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004510 const Expr *E = getCursorExpr(C);
4511 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004512 if (D) {
4513 CXCursor declCursor = MakeCXCursor(D, tu);
4514 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4515 declCursor);
4516 return declCursor;
4517 }
4518
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004519 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004520 return MakeCursorOverloadedDeclRef(Ovl, tu);
4521
4522 return clang_getNullCursor();
4523 }
4524
4525 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004526 const Stmt *S = getCursorStmt(C);
4527 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004528 if (LabelDecl *label = Goto->getLabel())
4529 if (LabelStmt *labelS = label->getStmt())
4530 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4531
4532 return clang_getNullCursor();
4533 }
4534
4535 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004536 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 return MakeMacroDefinitionCursor(Def, tu);
4538 }
4539
4540 if (!clang_isReference(C.kind))
4541 return clang_getNullCursor();
4542
4543 switch (C.kind) {
4544 case CXCursor_ObjCSuperClassRef:
4545 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4546
4547 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004548 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4549 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004550 return MakeCXCursor(Def, tu);
4551
4552 return MakeCXCursor(Prot, tu);
4553 }
4554
4555 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004556 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4557 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004558 return MakeCXCursor(Def, tu);
4559
4560 return MakeCXCursor(Class, tu);
4561 }
4562
4563 case CXCursor_TypeRef:
4564 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4565
4566 case CXCursor_TemplateRef:
4567 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4568
4569 case CXCursor_NamespaceRef:
4570 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4571
4572 case CXCursor_MemberRef:
4573 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4574
4575 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004576 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004577 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4578 tu ));
4579 }
4580
4581 case CXCursor_LabelRef:
4582 // FIXME: We end up faking the "parent" declaration here because we
4583 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004584 return MakeCXCursor(getCursorLabelRef(C).first,
4585 cxtu::getASTUnit(tu)->getASTContext()
4586 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004587 tu);
4588
4589 case CXCursor_OverloadedDeclRef:
4590 return C;
4591
4592 case CXCursor_VariableRef:
4593 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4594
4595 default:
4596 // We would prefer to enumerate all non-reference cursor kinds here.
4597 llvm_unreachable("Unhandled reference cursor kind");
4598 }
4599}
4600
4601CXCursor clang_getCursorDefinition(CXCursor C) {
4602 if (clang_isInvalid(C.kind))
4603 return clang_getNullCursor();
4604
4605 CXTranslationUnit TU = getCursorTU(C);
4606
4607 bool WasReference = false;
4608 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4609 C = clang_getCursorReferenced(C);
4610 WasReference = true;
4611 }
4612
4613 if (C.kind == CXCursor_MacroExpansion)
4614 return clang_getCursorReferenced(C);
4615
4616 if (!clang_isDeclaration(C.kind))
4617 return clang_getNullCursor();
4618
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004619 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004620 if (!D)
4621 return clang_getNullCursor();
4622
4623 switch (D->getKind()) {
4624 // Declaration kinds that don't really separate the notions of
4625 // declaration and definition.
4626 case Decl::Namespace:
4627 case Decl::Typedef:
4628 case Decl::TypeAlias:
4629 case Decl::TypeAliasTemplate:
4630 case Decl::TemplateTypeParm:
4631 case Decl::EnumConstant:
4632 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004633 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004634 case Decl::IndirectField:
4635 case Decl::ObjCIvar:
4636 case Decl::ObjCAtDefsField:
4637 case Decl::ImplicitParam:
4638 case Decl::ParmVar:
4639 case Decl::NonTypeTemplateParm:
4640 case Decl::TemplateTemplateParm:
4641 case Decl::ObjCCategoryImpl:
4642 case Decl::ObjCImplementation:
4643 case Decl::AccessSpec:
4644 case Decl::LinkageSpec:
4645 case Decl::ObjCPropertyImpl:
4646 case Decl::FileScopeAsm:
4647 case Decl::StaticAssert:
4648 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004649 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004650 case Decl::Label: // FIXME: Is this right??
4651 case Decl::ClassScopeFunctionSpecialization:
4652 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004653 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004654 return C;
4655
4656 // Declaration kinds that don't make any sense here, but are
4657 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004658 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004659 case Decl::TranslationUnit:
4660 break;
4661
4662 // Declaration kinds for which the definition is not resolvable.
4663 case Decl::UnresolvedUsingTypename:
4664 case Decl::UnresolvedUsingValue:
4665 break;
4666
4667 case Decl::UsingDirective:
4668 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4669 TU);
4670
4671 case Decl::NamespaceAlias:
4672 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4673
4674 case Decl::Enum:
4675 case Decl::Record:
4676 case Decl::CXXRecord:
4677 case Decl::ClassTemplateSpecialization:
4678 case Decl::ClassTemplatePartialSpecialization:
4679 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4680 return MakeCXCursor(Def, TU);
4681 return clang_getNullCursor();
4682
4683 case Decl::Function:
4684 case Decl::CXXMethod:
4685 case Decl::CXXConstructor:
4686 case Decl::CXXDestructor:
4687 case Decl::CXXConversion: {
4688 const FunctionDecl *Def = 0;
4689 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004690 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004691 return clang_getNullCursor();
4692 }
4693
Larisse Voufo39a1e502013-08-06 01:03:05 +00004694 case Decl::Var:
4695 case Decl::VarTemplateSpecialization:
4696 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004697 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004698 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004699 return MakeCXCursor(Def, TU);
4700 return clang_getNullCursor();
4701 }
4702
4703 case Decl::FunctionTemplate: {
4704 const FunctionDecl *Def = 0;
4705 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4706 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4707 return clang_getNullCursor();
4708 }
4709
4710 case Decl::ClassTemplate: {
4711 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4712 ->getDefinition())
4713 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4714 TU);
4715 return clang_getNullCursor();
4716 }
4717
Larisse Voufo39a1e502013-08-06 01:03:05 +00004718 case Decl::VarTemplate: {
4719 if (VarDecl *Def =
4720 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4721 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4722 return clang_getNullCursor();
4723 }
4724
Guy Benyei11169dd2012-12-18 14:30:41 +00004725 case Decl::Using:
4726 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4727 D->getLocation(), TU);
4728
4729 case Decl::UsingShadow:
4730 return clang_getCursorDefinition(
4731 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4732 TU));
4733
4734 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004735 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004736 if (Method->isThisDeclarationADefinition())
4737 return C;
4738
4739 // Dig out the method definition in the associated
4740 // @implementation, if we have it.
4741 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004742 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004743 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4744 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4745 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4746 Method->isInstanceMethod()))
4747 if (Def->isThisDeclarationADefinition())
4748 return MakeCXCursor(Def, TU);
4749
4750 return clang_getNullCursor();
4751 }
4752
4753 case Decl::ObjCCategory:
4754 if (ObjCCategoryImplDecl *Impl
4755 = cast<ObjCCategoryDecl>(D)->getImplementation())
4756 return MakeCXCursor(Impl, TU);
4757 return clang_getNullCursor();
4758
4759 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004760 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004761 return MakeCXCursor(Def, TU);
4762 return clang_getNullCursor();
4763
4764 case Decl::ObjCInterface: {
4765 // There are two notions of a "definition" for an Objective-C
4766 // class: the interface and its implementation. When we resolved a
4767 // reference to an Objective-C class, produce the @interface as
4768 // the definition; when we were provided with the interface,
4769 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004770 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004771 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004772 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004773 return MakeCXCursor(Def, TU);
4774 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4775 return MakeCXCursor(Impl, TU);
4776 return clang_getNullCursor();
4777 }
4778
4779 case Decl::ObjCProperty:
4780 // FIXME: We don't really know where to find the
4781 // ObjCPropertyImplDecls that implement this property.
4782 return clang_getNullCursor();
4783
4784 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004785 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004786 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004787 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004788 return MakeCXCursor(Def, TU);
4789
4790 return clang_getNullCursor();
4791
4792 case Decl::Friend:
4793 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4794 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4795 return clang_getNullCursor();
4796
4797 case Decl::FriendTemplate:
4798 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4799 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4800 return clang_getNullCursor();
4801 }
4802
4803 return clang_getNullCursor();
4804}
4805
4806unsigned clang_isCursorDefinition(CXCursor C) {
4807 if (!clang_isDeclaration(C.kind))
4808 return 0;
4809
4810 return clang_getCursorDefinition(C) == C;
4811}
4812
4813CXCursor clang_getCanonicalCursor(CXCursor C) {
4814 if (!clang_isDeclaration(C.kind))
4815 return C;
4816
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004817 if (const Decl *D = getCursorDecl(C)) {
4818 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004819 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4820 return MakeCXCursor(CatD, getCursorTU(C));
4821
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004822 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4823 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004824 return MakeCXCursor(IFD, getCursorTU(C));
4825
4826 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4827 }
4828
4829 return C;
4830}
4831
4832int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4833 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4834}
4835
4836unsigned clang_getNumOverloadedDecls(CXCursor C) {
4837 if (C.kind != CXCursor_OverloadedDeclRef)
4838 return 0;
4839
4840 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004841 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004842 return E->getNumDecls();
4843
4844 if (OverloadedTemplateStorage *S
4845 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4846 return S->size();
4847
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004848 const Decl *D = Storage.get<const Decl *>();
4849 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004850 return Using->shadow_size();
4851
4852 return 0;
4853}
4854
4855CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4856 if (cursor.kind != CXCursor_OverloadedDeclRef)
4857 return clang_getNullCursor();
4858
4859 if (index >= clang_getNumOverloadedDecls(cursor))
4860 return clang_getNullCursor();
4861
4862 CXTranslationUnit TU = getCursorTU(cursor);
4863 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004864 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004865 return MakeCXCursor(E->decls_begin()[index], TU);
4866
4867 if (OverloadedTemplateStorage *S
4868 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4869 return MakeCXCursor(S->begin()[index], TU);
4870
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004871 const Decl *D = Storage.get<const Decl *>();
4872 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004873 // FIXME: This is, unfortunately, linear time.
4874 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4875 std::advance(Pos, index);
4876 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4877 }
4878
4879 return clang_getNullCursor();
4880}
4881
4882void clang_getDefinitionSpellingAndExtent(CXCursor C,
4883 const char **startBuf,
4884 const char **endBuf,
4885 unsigned *startLine,
4886 unsigned *startColumn,
4887 unsigned *endLine,
4888 unsigned *endColumn) {
4889 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004890 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004891 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4892
4893 SourceManager &SM = FD->getASTContext().getSourceManager();
4894 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4895 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4896 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4897 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4898 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4899 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4900}
4901
4902
4903CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4904 unsigned PieceIndex) {
4905 RefNamePieces Pieces;
4906
4907 switch (C.kind) {
4908 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004909 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004910 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4911 E->getQualifierLoc().getSourceRange());
4912 break;
4913
4914 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004915 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004916 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4917 E->getQualifierLoc().getSourceRange(),
4918 E->getOptionalExplicitTemplateArgs());
4919 break;
4920
4921 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004922 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004923 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004924 const Expr *Callee = OCE->getCallee();
4925 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004926 Callee = ICE->getSubExpr();
4927
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004928 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004929 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4930 DRE->getQualifierLoc().getSourceRange());
4931 }
4932 break;
4933
4934 default:
4935 break;
4936 }
4937
4938 if (Pieces.empty()) {
4939 if (PieceIndex == 0)
4940 return clang_getCursorExtent(C);
4941 } else if (PieceIndex < Pieces.size()) {
4942 SourceRange R = Pieces[PieceIndex];
4943 if (R.isValid())
4944 return cxloc::translateSourceRange(getCursorContext(C), R);
4945 }
4946
4947 return clang_getNullRange();
4948}
4949
4950void clang_enableStackTraces(void) {
4951 llvm::sys::PrintStackTraceOnErrorSignal();
4952}
4953
4954void clang_executeOnThread(void (*fn)(void*), void *user_data,
4955 unsigned stack_size) {
4956 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4957}
4958
4959} // end: extern "C"
4960
4961//===----------------------------------------------------------------------===//
4962// Token-based Operations.
4963//===----------------------------------------------------------------------===//
4964
4965/* CXToken layout:
4966 * int_data[0]: a CXTokenKind
4967 * int_data[1]: starting token location
4968 * int_data[2]: token length
4969 * int_data[3]: reserved
4970 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4971 * otherwise unused.
4972 */
4973extern "C" {
4974
4975CXTokenKind clang_getTokenKind(CXToken CXTok) {
4976 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4977}
4978
4979CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4980 switch (clang_getTokenKind(CXTok)) {
4981 case CXToken_Identifier:
4982 case CXToken_Keyword:
4983 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004984 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004985 ->getNameStart());
4986
4987 case CXToken_Literal: {
4988 // We have stashed the starting pointer in the ptr_data field. Use it.
4989 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004990 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004991 }
4992
4993 case CXToken_Punctuation:
4994 case CXToken_Comment:
4995 break;
4996 }
4997
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004998 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004999 LOG_BAD_TU(TU);
5000 return cxstring::createEmpty();
5001 }
5002
Guy Benyei11169dd2012-12-18 14:30:41 +00005003 // We have to find the starting buffer pointer the hard way, by
5004 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005005 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005006 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005007 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005008
5009 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5010 std::pair<FileID, unsigned> LocInfo
5011 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5012 bool Invalid = false;
5013 StringRef Buffer
5014 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5015 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005016 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005017
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005018 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005019}
5020
5021CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005022 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005023 LOG_BAD_TU(TU);
5024 return clang_getNullLocation();
5025 }
5026
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005027 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005028 if (!CXXUnit)
5029 return clang_getNullLocation();
5030
5031 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5032 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5033}
5034
5035CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005036 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005037 LOG_BAD_TU(TU);
5038 return clang_getNullRange();
5039 }
5040
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005041 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005042 if (!CXXUnit)
5043 return clang_getNullRange();
5044
5045 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5046 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5047}
5048
5049static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5050 SmallVectorImpl<CXToken> &CXTokens) {
5051 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5052 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005053 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005054 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005055 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005056
5057 // Cannot tokenize across files.
5058 if (BeginLocInfo.first != EndLocInfo.first)
5059 return;
5060
5061 // Create a lexer
5062 bool Invalid = false;
5063 StringRef Buffer
5064 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5065 if (Invalid)
5066 return;
5067
5068 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5069 CXXUnit->getASTContext().getLangOpts(),
5070 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5071 Lex.SetCommentRetentionState(true);
5072
5073 // Lex tokens until we hit the end of the range.
5074 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5075 Token Tok;
5076 bool previousWasAt = false;
5077 do {
5078 // Lex the next token
5079 Lex.LexFromRawLexer(Tok);
5080 if (Tok.is(tok::eof))
5081 break;
5082
5083 // Initialize the CXToken.
5084 CXToken CXTok;
5085
5086 // - Common fields
5087 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5088 CXTok.int_data[2] = Tok.getLength();
5089 CXTok.int_data[3] = 0;
5090
5091 // - Kind-specific fields
5092 if (Tok.isLiteral()) {
5093 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005094 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005095 } else if (Tok.is(tok::raw_identifier)) {
5096 // Lookup the identifier to determine whether we have a keyword.
5097 IdentifierInfo *II
5098 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5099
5100 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5101 CXTok.int_data[0] = CXToken_Keyword;
5102 }
5103 else {
5104 CXTok.int_data[0] = Tok.is(tok::identifier)
5105 ? CXToken_Identifier
5106 : CXToken_Keyword;
5107 }
5108 CXTok.ptr_data = II;
5109 } else if (Tok.is(tok::comment)) {
5110 CXTok.int_data[0] = CXToken_Comment;
5111 CXTok.ptr_data = 0;
5112 } else {
5113 CXTok.int_data[0] = CXToken_Punctuation;
5114 CXTok.ptr_data = 0;
5115 }
5116 CXTokens.push_back(CXTok);
5117 previousWasAt = Tok.is(tok::at);
5118 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5119}
5120
5121void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5122 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005123 LOG_FUNC_SECTION {
5124 *Log << TU << ' ' << Range;
5125 }
5126
Guy Benyei11169dd2012-12-18 14:30:41 +00005127 if (Tokens)
5128 *Tokens = 0;
5129 if (NumTokens)
5130 *NumTokens = 0;
5131
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005132 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005133 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005134 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005135 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005136
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005137 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005138 if (!CXXUnit || !Tokens || !NumTokens)
5139 return;
5140
5141 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5142
5143 SourceRange R = cxloc::translateCXSourceRange(Range);
5144 if (R.isInvalid())
5145 return;
5146
5147 SmallVector<CXToken, 32> CXTokens;
5148 getTokens(CXXUnit, R, CXTokens);
5149
5150 if (CXTokens.empty())
5151 return;
5152
5153 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5154 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5155 *NumTokens = CXTokens.size();
5156}
5157
5158void clang_disposeTokens(CXTranslationUnit TU,
5159 CXToken *Tokens, unsigned NumTokens) {
5160 free(Tokens);
5161}
5162
5163} // end: extern "C"
5164
5165//===----------------------------------------------------------------------===//
5166// Token annotation APIs.
5167//===----------------------------------------------------------------------===//
5168
Guy Benyei11169dd2012-12-18 14:30:41 +00005169static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5170 CXCursor parent,
5171 CXClientData client_data);
5172static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5173 CXClientData client_data);
5174
5175namespace {
5176class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005177 CXToken *Tokens;
5178 CXCursor *Cursors;
5179 unsigned NumTokens;
5180 unsigned TokIdx;
5181 unsigned PreprocessingTokIdx;
5182 CursorVisitor AnnotateVis;
5183 SourceManager &SrcMgr;
5184 bool HasContextSensitiveKeywords;
5185
5186 struct PostChildrenInfo {
5187 CXCursor Cursor;
5188 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005189 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005190 unsigned BeforeChildrenTokenIdx;
5191 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005192 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005193
5194 CXToken &getTok(unsigned Idx) {
5195 assert(Idx < NumTokens);
5196 return Tokens[Idx];
5197 }
5198 const CXToken &getTok(unsigned Idx) const {
5199 assert(Idx < NumTokens);
5200 return Tokens[Idx];
5201 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005202 bool MoreTokens() const { return TokIdx < NumTokens; }
5203 unsigned NextToken() const { return TokIdx; }
5204 void AdvanceToken() { ++TokIdx; }
5205 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005206 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005207 }
5208 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005209 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 }
5211 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005212 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005213 }
5214
5215 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005216 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005217 SourceRange);
5218
5219public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005220 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005221 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005222 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005223 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005224 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005225 AnnotateTokensVisitor, this,
5226 /*VisitPreprocessorLast=*/true,
5227 /*VisitIncludedEntities=*/false,
5228 RegionOfInterest,
5229 /*VisitDeclsOnly=*/false,
5230 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005231 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005232 HasContextSensitiveKeywords(false) { }
5233
5234 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5235 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5236 bool postVisitChildren(CXCursor cursor);
5237 void AnnotateTokens();
5238
5239 /// \brief Determine whether the annotator saw any cursors that have
5240 /// context-sensitive keywords.
5241 bool hasContextSensitiveKeywords() const {
5242 return HasContextSensitiveKeywords;
5243 }
5244
5245 ~AnnotateTokensWorker() {
5246 assert(PostChildrenInfos.empty());
5247 }
5248};
5249}
5250
5251void AnnotateTokensWorker::AnnotateTokens() {
5252 // Walk the AST within the region of interest, annotating tokens
5253 // along the way.
5254 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005255}
Guy Benyei11169dd2012-12-18 14:30:41 +00005256
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005257static inline void updateCursorAnnotation(CXCursor &Cursor,
5258 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005259 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005260 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005261 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005262}
5263
5264/// \brief It annotates and advances tokens with a cursor until the comparison
5265//// between the cursor location and the source range is the same as
5266/// \arg compResult.
5267///
5268/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5269/// Pass RangeOverlap to annotate tokens inside a range.
5270void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5271 RangeComparisonResult compResult,
5272 SourceRange range) {
5273 while (MoreTokens()) {
5274 const unsigned I = NextToken();
5275 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005276 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5277 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005278
5279 SourceLocation TokLoc = GetTokenLoc(I);
5280 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005281 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005282 AdvanceToken();
5283 continue;
5284 }
5285 break;
5286 }
5287}
5288
5289/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005290/// \returns true if it advanced beyond all macro tokens, false otherwise.
5291bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005292 CXCursor updateC,
5293 RangeComparisonResult compResult,
5294 SourceRange range) {
5295 assert(MoreTokens());
5296 assert(isFunctionMacroToken(NextToken()) &&
5297 "Should be called only for macro arg tokens");
5298
5299 // This works differently than annotateAndAdvanceTokens; because expanded
5300 // macro arguments can have arbitrary translation-unit source order, we do not
5301 // advance the token index one by one until a token fails the range test.
5302 // We only advance once past all of the macro arg tokens if all of them
5303 // pass the range test. If one of them fails we keep the token index pointing
5304 // at the start of the macro arg tokens so that the failing token will be
5305 // annotated by a subsequent annotation try.
5306
5307 bool atLeastOneCompFail = false;
5308
5309 unsigned I = NextToken();
5310 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5311 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5312 if (TokLoc.isFileID())
5313 continue; // not macro arg token, it's parens or comma.
5314 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5315 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5316 Cursors[I] = updateC;
5317 } else
5318 atLeastOneCompFail = true;
5319 }
5320
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005321 if (atLeastOneCompFail)
5322 return false;
5323
5324 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5325 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005326}
5327
5328enum CXChildVisitResult
5329AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005330 SourceRange cursorRange = getRawCursorExtent(cursor);
5331 if (cursorRange.isInvalid())
5332 return CXChildVisit_Recurse;
5333
5334 if (!HasContextSensitiveKeywords) {
5335 // Objective-C properties can have context-sensitive keywords.
5336 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005337 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005338 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5339 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5340 }
5341 // Objective-C methods can have context-sensitive keywords.
5342 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5343 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005344 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005345 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5346 if (Method->getObjCDeclQualifier())
5347 HasContextSensitiveKeywords = true;
5348 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005349 for (const auto *P : Method->params()) {
5350 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005351 HasContextSensitiveKeywords = true;
5352 break;
5353 }
5354 }
5355 }
5356 }
5357 }
5358 // C++ methods can have context-sensitive keywords.
5359 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005360 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005361 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5362 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5363 HasContextSensitiveKeywords = true;
5364 }
5365 }
5366 // C++ classes can have context-sensitive keywords.
5367 else if (cursor.kind == CXCursor_StructDecl ||
5368 cursor.kind == CXCursor_ClassDecl ||
5369 cursor.kind == CXCursor_ClassTemplate ||
5370 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005371 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005372 if (D->hasAttr<FinalAttr>())
5373 HasContextSensitiveKeywords = true;
5374 }
5375 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005376
5377 // Don't override a property annotation with its getter/setter method.
5378 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5379 parent.kind == CXCursor_ObjCPropertyDecl)
5380 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005381
5382 if (clang_isPreprocessing(cursor.kind)) {
5383 // Items in the preprocessing record are kept separate from items in
5384 // declarations, so we keep a separate token index.
5385 unsigned SavedTokIdx = TokIdx;
5386 TokIdx = PreprocessingTokIdx;
5387
5388 // Skip tokens up until we catch up to the beginning of the preprocessing
5389 // entry.
5390 while (MoreTokens()) {
5391 const unsigned I = NextToken();
5392 SourceLocation TokLoc = GetTokenLoc(I);
5393 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5394 case RangeBefore:
5395 AdvanceToken();
5396 continue;
5397 case RangeAfter:
5398 case RangeOverlap:
5399 break;
5400 }
5401 break;
5402 }
5403
5404 // Look at all of the tokens within this range.
5405 while (MoreTokens()) {
5406 const unsigned I = NextToken();
5407 SourceLocation TokLoc = GetTokenLoc(I);
5408 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5409 case RangeBefore:
5410 llvm_unreachable("Infeasible");
5411 case RangeAfter:
5412 break;
5413 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005414 // For macro expansions, just note where the beginning of the macro
5415 // expansion occurs.
5416 if (cursor.kind == CXCursor_MacroExpansion) {
5417 if (TokLoc == cursorRange.getBegin())
5418 Cursors[I] = cursor;
5419 AdvanceToken();
5420 break;
5421 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005422 // We may have already annotated macro names inside macro definitions.
5423 if (Cursors[I].kind != CXCursor_MacroExpansion)
5424 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005425 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005426 continue;
5427 }
5428 break;
5429 }
5430
5431 // Save the preprocessing token index; restore the non-preprocessing
5432 // token index.
5433 PreprocessingTokIdx = TokIdx;
5434 TokIdx = SavedTokIdx;
5435 return CXChildVisit_Recurse;
5436 }
5437
5438 if (cursorRange.isInvalid())
5439 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005440
5441 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005442 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005443 const enum CXCursorKind K = clang_getCursorKind(parent);
5444 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005445 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5446 // Attributes are annotated out-of-order, skip tokens until we reach it.
5447 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005448 ? clang_getNullCursor() : parent;
5449
5450 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5451
5452 // Avoid having the cursor of an expression "overwrite" the annotation of the
5453 // variable declaration that it belongs to.
5454 // This can happen for C++ constructor expressions whose range generally
5455 // include the variable declaration, e.g.:
5456 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005457 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005458 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005459 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005460 const unsigned I = NextToken();
5461 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5462 E->getLocStart() == D->getLocation() &&
5463 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005464 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005465 AdvanceToken();
5466 }
5467 }
5468 }
5469
5470 // Before recursing into the children keep some state that we are going
5471 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5472 // extra work after the child nodes are visited.
5473 // Note that we don't call VisitChildren here to avoid traversing statements
5474 // code-recursively which can blow the stack.
5475
5476 PostChildrenInfo Info;
5477 Info.Cursor = cursor;
5478 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005479 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005480 Info.BeforeChildrenTokenIdx = NextToken();
5481 PostChildrenInfos.push_back(Info);
5482
5483 return CXChildVisit_Recurse;
5484}
5485
5486bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5487 if (PostChildrenInfos.empty())
5488 return false;
5489 const PostChildrenInfo &Info = PostChildrenInfos.back();
5490 if (!clang_equalCursors(Info.Cursor, cursor))
5491 return false;
5492
5493 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5494 const unsigned AfterChildren = NextToken();
5495 SourceRange cursorRange = Info.CursorRange;
5496
5497 // Scan the tokens that are at the end of the cursor, but are not captured
5498 // but the child cursors.
5499 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5500
5501 // Scan the tokens that are at the beginning of the cursor, but are not
5502 // capture by the child cursors.
5503 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5504 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5505 break;
5506
5507 Cursors[I] = cursor;
5508 }
5509
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005510 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5511 // encountered the attribute cursor.
5512 if (clang_isAttribute(cursor.kind))
5513 TokIdx = Info.BeforeReachingCursorIdx;
5514
Guy Benyei11169dd2012-12-18 14:30:41 +00005515 PostChildrenInfos.pop_back();
5516 return false;
5517}
5518
5519static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5520 CXCursor parent,
5521 CXClientData client_data) {
5522 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5523}
5524
5525static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5526 CXClientData client_data) {
5527 return static_cast<AnnotateTokensWorker*>(client_data)->
5528 postVisitChildren(cursor);
5529}
5530
5531namespace {
5532
5533/// \brief Uses the macro expansions in the preprocessing record to find
5534/// and mark tokens that are macro arguments. This info is used by the
5535/// AnnotateTokensWorker.
5536class MarkMacroArgTokensVisitor {
5537 SourceManager &SM;
5538 CXToken *Tokens;
5539 unsigned NumTokens;
5540 unsigned CurIdx;
5541
5542public:
5543 MarkMacroArgTokensVisitor(SourceManager &SM,
5544 CXToken *tokens, unsigned numTokens)
5545 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5546
5547 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5548 if (cursor.kind != CXCursor_MacroExpansion)
5549 return CXChildVisit_Continue;
5550
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005551 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005552 if (macroRange.getBegin() == macroRange.getEnd())
5553 return CXChildVisit_Continue; // it's not a function macro.
5554
5555 for (; CurIdx < NumTokens; ++CurIdx) {
5556 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5557 macroRange.getBegin()))
5558 break;
5559 }
5560
5561 if (CurIdx == NumTokens)
5562 return CXChildVisit_Break;
5563
5564 for (; CurIdx < NumTokens; ++CurIdx) {
5565 SourceLocation tokLoc = getTokenLoc(CurIdx);
5566 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5567 break;
5568
5569 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5570 }
5571
5572 if (CurIdx == NumTokens)
5573 return CXChildVisit_Break;
5574
5575 return CXChildVisit_Continue;
5576 }
5577
5578private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005579 CXToken &getTok(unsigned Idx) {
5580 assert(Idx < NumTokens);
5581 return Tokens[Idx];
5582 }
5583 const CXToken &getTok(unsigned Idx) const {
5584 assert(Idx < NumTokens);
5585 return Tokens[Idx];
5586 }
5587
Guy Benyei11169dd2012-12-18 14:30:41 +00005588 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005589 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005590 }
5591
5592 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5593 // The third field is reserved and currently not used. Use it here
5594 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005595 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005596 }
5597};
5598
5599} // end anonymous namespace
5600
5601static CXChildVisitResult
5602MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5603 CXClientData client_data) {
5604 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5605 parent);
5606}
5607
5608namespace {
5609 struct clang_annotateTokens_Data {
5610 CXTranslationUnit TU;
5611 ASTUnit *CXXUnit;
5612 CXToken *Tokens;
5613 unsigned NumTokens;
5614 CXCursor *Cursors;
5615 };
5616}
5617
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005618/// \brief Used by \c annotatePreprocessorTokens.
5619/// \returns true if lexing was finished, false otherwise.
5620static bool lexNext(Lexer &Lex, Token &Tok,
5621 unsigned &NextIdx, unsigned NumTokens) {
5622 if (NextIdx >= NumTokens)
5623 return true;
5624
5625 ++NextIdx;
5626 Lex.LexFromRawLexer(Tok);
5627 if (Tok.is(tok::eof))
5628 return true;
5629
5630 return false;
5631}
5632
Guy Benyei11169dd2012-12-18 14:30:41 +00005633static void annotatePreprocessorTokens(CXTranslationUnit TU,
5634 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005635 CXCursor *Cursors,
5636 CXToken *Tokens,
5637 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005638 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005639
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005640 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005641 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5642 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005643 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005644 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005645 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005646
5647 if (BeginLocInfo.first != EndLocInfo.first)
5648 return;
5649
5650 StringRef Buffer;
5651 bool Invalid = false;
5652 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5653 if (Buffer.empty() || Invalid)
5654 return;
5655
5656 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5657 CXXUnit->getASTContext().getLangOpts(),
5658 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5659 Buffer.end());
5660 Lex.SetCommentRetentionState(true);
5661
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005662 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005663 // Lex tokens in raw mode until we hit the end of the range, to avoid
5664 // entering #includes or expanding macros.
5665 while (true) {
5666 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005667 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5668 break;
5669 unsigned TokIdx = NextIdx-1;
5670 assert(Tok.getLocation() ==
5671 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005672
5673 reprocess:
5674 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005675 // We have found a preprocessing directive. Annotate the tokens
5676 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005677 //
5678 // FIXME: Some simple tests here could identify macro definitions and
5679 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005680
5681 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005682 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5683 break;
5684
5685 MacroInfo *MI = 0;
5686 if (Tok.is(tok::raw_identifier) &&
5687 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5688 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5689 break;
5690
5691 if (Tok.is(tok::raw_identifier)) {
5692 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5693 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5694 SourceLocation MappedTokLoc =
5695 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5696 MI = getMacroInfo(II, MappedTokLoc, TU);
5697 }
5698 }
5699
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005700 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005701 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005702 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5703 finished = true;
5704 break;
5705 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005706 // If we are in a macro definition, check if the token was ever a
5707 // macro name and annotate it if that's the case.
5708 if (MI) {
5709 SourceLocation SaveLoc = Tok.getLocation();
5710 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5711 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5712 Tok.setLocation(SaveLoc);
5713 if (MacroDef)
5714 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5715 Tok.getLocation(), TU);
5716 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005717 } while (!Tok.isAtStartOfLine());
5718
5719 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5720 assert(TokIdx <= LastIdx);
5721 SourceLocation EndLoc =
5722 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5723 CXCursor Cursor =
5724 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5725
5726 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005727 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005728
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005729 if (finished)
5730 break;
5731 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005732 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005733 }
5734}
5735
5736// This gets run a separate thread to avoid stack blowout.
5737static void clang_annotateTokensImpl(void *UserData) {
5738 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5739 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5740 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5741 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5742 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5743
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005744 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005745 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5746 setThreadBackgroundPriority();
5747
5748 // Determine the region of interest, which contains all of the tokens.
5749 SourceRange RegionOfInterest;
5750 RegionOfInterest.setBegin(
5751 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5752 RegionOfInterest.setEnd(
5753 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5754 Tokens[NumTokens-1])));
5755
Guy Benyei11169dd2012-12-18 14:30:41 +00005756 // Relex the tokens within the source range to look for preprocessing
5757 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005758 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005759
5760 // If begin location points inside a macro argument, set it to the expansion
5761 // location so we can have the full context when annotating semantically.
5762 {
5763 SourceManager &SM = CXXUnit->getSourceManager();
5764 SourceLocation Loc =
5765 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5766 if (Loc.isMacroID())
5767 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5768 }
5769
Guy Benyei11169dd2012-12-18 14:30:41 +00005770 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5771 // Search and mark tokens that are macro argument expansions.
5772 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5773 Tokens, NumTokens);
5774 CursorVisitor MacroArgMarker(TU,
5775 MarkMacroArgTokensVisitorDelegate, &Visitor,
5776 /*VisitPreprocessorLast=*/true,
5777 /*VisitIncludedEntities=*/false,
5778 RegionOfInterest);
5779 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5780 }
5781
5782 // Annotate all of the source locations in the region of interest that map to
5783 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005784 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005785
5786 // FIXME: We use a ridiculous stack size here because the data-recursion
5787 // algorithm uses a large stack frame than the non-data recursive version,
5788 // and AnnotationTokensWorker currently transforms the data-recursion
5789 // algorithm back into a traditional recursion by explicitly calling
5790 // VisitChildren(). We will need to remove this explicit recursive call.
5791 W.AnnotateTokens();
5792
5793 // If we ran into any entities that involve context-sensitive keywords,
5794 // take another pass through the tokens to mark them as such.
5795 if (W.hasContextSensitiveKeywords()) {
5796 for (unsigned I = 0; I != NumTokens; ++I) {
5797 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5798 continue;
5799
5800 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5801 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005802 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005803 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5804 if (Property->getPropertyAttributesAsWritten() != 0 &&
5805 llvm::StringSwitch<bool>(II->getName())
5806 .Case("readonly", true)
5807 .Case("assign", true)
5808 .Case("unsafe_unretained", true)
5809 .Case("readwrite", true)
5810 .Case("retain", true)
5811 .Case("copy", true)
5812 .Case("nonatomic", true)
5813 .Case("atomic", true)
5814 .Case("getter", true)
5815 .Case("setter", true)
5816 .Case("strong", true)
5817 .Case("weak", true)
5818 .Default(false))
5819 Tokens[I].int_data[0] = CXToken_Keyword;
5820 }
5821 continue;
5822 }
5823
5824 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5825 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5826 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5827 if (llvm::StringSwitch<bool>(II->getName())
5828 .Case("in", true)
5829 .Case("out", true)
5830 .Case("inout", true)
5831 .Case("oneway", true)
5832 .Case("bycopy", true)
5833 .Case("byref", true)
5834 .Default(false))
5835 Tokens[I].int_data[0] = CXToken_Keyword;
5836 continue;
5837 }
5838
5839 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5840 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5841 Tokens[I].int_data[0] = CXToken_Keyword;
5842 continue;
5843 }
5844 }
5845 }
5846}
5847
5848extern "C" {
5849
5850void clang_annotateTokens(CXTranslationUnit TU,
5851 CXToken *Tokens, unsigned NumTokens,
5852 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005853 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005854 LOG_BAD_TU(TU);
5855 return;
5856 }
5857 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005858 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005859 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005860 }
5861
5862 LOG_FUNC_SECTION {
5863 *Log << TU << ' ';
5864 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5865 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5866 *Log << clang_getRange(bloc, eloc);
5867 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005868
5869 // Any token we don't specifically annotate will have a NULL cursor.
5870 CXCursor C = clang_getNullCursor();
5871 for (unsigned I = 0; I != NumTokens; ++I)
5872 Cursors[I] = C;
5873
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005874 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005875 if (!CXXUnit)
5876 return;
5877
5878 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5879
5880 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5881 llvm::CrashRecoveryContext CRC;
5882 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5883 GetSafetyThreadStackSize() * 2)) {
5884 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5885 }
5886}
5887
5888} // end: extern "C"
5889
5890//===----------------------------------------------------------------------===//
5891// Operations for querying linkage of a cursor.
5892//===----------------------------------------------------------------------===//
5893
5894extern "C" {
5895CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5896 if (!clang_isDeclaration(cursor.kind))
5897 return CXLinkage_Invalid;
5898
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005899 const Decl *D = cxcursor::getCursorDecl(cursor);
5900 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005901 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005902 case NoLinkage:
5903 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005904 case InternalLinkage: return CXLinkage_Internal;
5905 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5906 case ExternalLinkage: return CXLinkage_External;
5907 };
5908
5909 return CXLinkage_Invalid;
5910}
5911} // end: extern "C"
5912
5913//===----------------------------------------------------------------------===//
5914// Operations for querying language of a cursor.
5915//===----------------------------------------------------------------------===//
5916
5917static CXLanguageKind getDeclLanguage(const Decl *D) {
5918 if (!D)
5919 return CXLanguage_C;
5920
5921 switch (D->getKind()) {
5922 default:
5923 break;
5924 case Decl::ImplicitParam:
5925 case Decl::ObjCAtDefsField:
5926 case Decl::ObjCCategory:
5927 case Decl::ObjCCategoryImpl:
5928 case Decl::ObjCCompatibleAlias:
5929 case Decl::ObjCImplementation:
5930 case Decl::ObjCInterface:
5931 case Decl::ObjCIvar:
5932 case Decl::ObjCMethod:
5933 case Decl::ObjCProperty:
5934 case Decl::ObjCPropertyImpl:
5935 case Decl::ObjCProtocol:
5936 return CXLanguage_ObjC;
5937 case Decl::CXXConstructor:
5938 case Decl::CXXConversion:
5939 case Decl::CXXDestructor:
5940 case Decl::CXXMethod:
5941 case Decl::CXXRecord:
5942 case Decl::ClassTemplate:
5943 case Decl::ClassTemplatePartialSpecialization:
5944 case Decl::ClassTemplateSpecialization:
5945 case Decl::Friend:
5946 case Decl::FriendTemplate:
5947 case Decl::FunctionTemplate:
5948 case Decl::LinkageSpec:
5949 case Decl::Namespace:
5950 case Decl::NamespaceAlias:
5951 case Decl::NonTypeTemplateParm:
5952 case Decl::StaticAssert:
5953 case Decl::TemplateTemplateParm:
5954 case Decl::TemplateTypeParm:
5955 case Decl::UnresolvedUsingTypename:
5956 case Decl::UnresolvedUsingValue:
5957 case Decl::Using:
5958 case Decl::UsingDirective:
5959 case Decl::UsingShadow:
5960 return CXLanguage_CPlusPlus;
5961 }
5962
5963 return CXLanguage_C;
5964}
5965
5966extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005967
5968static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5969 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5970 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005971
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005972 switch (D->getAvailability()) {
5973 case AR_Available:
5974 case AR_NotYetIntroduced:
5975 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005976 return getCursorAvailabilityForDecl(
5977 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005978 return CXAvailability_Available;
5979
5980 case AR_Deprecated:
5981 return CXAvailability_Deprecated;
5982
5983 case AR_Unavailable:
5984 return CXAvailability_NotAvailable;
5985 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005986
5987 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005988}
5989
Guy Benyei11169dd2012-12-18 14:30:41 +00005990enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5991 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005992 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5993 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005994
5995 return CXAvailability_Available;
5996}
5997
5998static CXVersion convertVersion(VersionTuple In) {
5999 CXVersion Out = { -1, -1, -1 };
6000 if (In.empty())
6001 return Out;
6002
6003 Out.Major = In.getMajor();
6004
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006005 Optional<unsigned> Minor = In.getMinor();
6006 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006007 Out.Minor = *Minor;
6008 else
6009 return Out;
6010
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006011 Optional<unsigned> Subminor = In.getSubminor();
6012 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006013 Out.Subminor = *Subminor;
6014
6015 return Out;
6016}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006017
6018static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6019 int *always_deprecated,
6020 CXString *deprecated_message,
6021 int *always_unavailable,
6022 CXString *unavailable_message,
6023 CXPlatformAvailability *availability,
6024 int availability_size) {
6025 bool HadAvailAttr = false;
6026 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006027 for (auto A : D->attrs()) {
6028 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006029 HadAvailAttr = true;
6030 if (always_deprecated)
6031 *always_deprecated = 1;
6032 if (deprecated_message)
6033 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
6034 continue;
6035 }
6036
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006037 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006038 HadAvailAttr = true;
6039 if (always_unavailable)
6040 *always_unavailable = 1;
6041 if (unavailable_message) {
6042 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6043 }
6044 continue;
6045 }
6046
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006047 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006048 HadAvailAttr = true;
6049 if (N < availability_size) {
6050 availability[N].Platform
6051 = cxstring::createDup(Avail->getPlatform()->getName());
6052 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6053 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6054 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6055 availability[N].Unavailable = Avail->getUnavailable();
6056 availability[N].Message = cxstring::createDup(Avail->getMessage());
6057 }
6058 ++N;
6059 }
6060 }
6061
6062 if (!HadAvailAttr)
6063 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6064 return getCursorPlatformAvailabilityForDecl(
6065 cast<Decl>(EnumConst->getDeclContext()),
6066 always_deprecated,
6067 deprecated_message,
6068 always_unavailable,
6069 unavailable_message,
6070 availability,
6071 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006072
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006073 return N;
6074}
6075
Guy Benyei11169dd2012-12-18 14:30:41 +00006076int clang_getCursorPlatformAvailability(CXCursor cursor,
6077 int *always_deprecated,
6078 CXString *deprecated_message,
6079 int *always_unavailable,
6080 CXString *unavailable_message,
6081 CXPlatformAvailability *availability,
6082 int availability_size) {
6083 if (always_deprecated)
6084 *always_deprecated = 0;
6085 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006086 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006087 if (always_unavailable)
6088 *always_unavailable = 0;
6089 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006090 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006091
Guy Benyei11169dd2012-12-18 14:30:41 +00006092 if (!clang_isDeclaration(cursor.kind))
6093 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006094
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006095 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006096 if (!D)
6097 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006098
6099 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6100 deprecated_message,
6101 always_unavailable,
6102 unavailable_message,
6103 availability,
6104 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006105}
6106
6107void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6108 clang_disposeString(availability->Platform);
6109 clang_disposeString(availability->Message);
6110}
6111
6112CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6113 if (clang_isDeclaration(cursor.kind))
6114 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6115
6116 return CXLanguage_Invalid;
6117}
6118
6119 /// \brief If the given cursor is the "templated" declaration
6120 /// descibing a class or function template, return the class or
6121 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006122static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006123 if (!D)
6124 return 0;
6125
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006126 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006127 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6128 return FunTmpl;
6129
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006130 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006131 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6132 return ClassTmpl;
6133
6134 return D;
6135}
6136
6137CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6138 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006139 if (const Decl *D = getCursorDecl(cursor)) {
6140 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006141 if (!DC)
6142 return clang_getNullCursor();
6143
6144 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6145 getCursorTU(cursor));
6146 }
6147 }
6148
6149 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006150 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006151 return MakeCXCursor(D, getCursorTU(cursor));
6152 }
6153
6154 return clang_getNullCursor();
6155}
6156
6157CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6158 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006159 if (const Decl *D = getCursorDecl(cursor)) {
6160 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006161 if (!DC)
6162 return clang_getNullCursor();
6163
6164 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6165 getCursorTU(cursor));
6166 }
6167 }
6168
6169 // FIXME: Note that we can't easily compute the lexical context of a
6170 // statement or expression, so we return nothing.
6171 return clang_getNullCursor();
6172}
6173
6174CXFile clang_getIncludedFile(CXCursor cursor) {
6175 if (cursor.kind != CXCursor_InclusionDirective)
6176 return 0;
6177
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006178 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006179 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006180}
6181
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006182unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6183 if (C.kind != CXCursor_ObjCPropertyDecl)
6184 return CXObjCPropertyAttr_noattr;
6185
6186 unsigned Result = CXObjCPropertyAttr_noattr;
6187 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6188 ObjCPropertyDecl::PropertyAttributeKind Attr =
6189 PD->getPropertyAttributesAsWritten();
6190
6191#define SET_CXOBJCPROP_ATTR(A) \
6192 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6193 Result |= CXObjCPropertyAttr_##A
6194 SET_CXOBJCPROP_ATTR(readonly);
6195 SET_CXOBJCPROP_ATTR(getter);
6196 SET_CXOBJCPROP_ATTR(assign);
6197 SET_CXOBJCPROP_ATTR(readwrite);
6198 SET_CXOBJCPROP_ATTR(retain);
6199 SET_CXOBJCPROP_ATTR(copy);
6200 SET_CXOBJCPROP_ATTR(nonatomic);
6201 SET_CXOBJCPROP_ATTR(setter);
6202 SET_CXOBJCPROP_ATTR(atomic);
6203 SET_CXOBJCPROP_ATTR(weak);
6204 SET_CXOBJCPROP_ATTR(strong);
6205 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6206#undef SET_CXOBJCPROP_ATTR
6207
6208 return Result;
6209}
6210
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006211unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6212 if (!clang_isDeclaration(C.kind))
6213 return CXObjCDeclQualifier_None;
6214
6215 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6216 const Decl *D = getCursorDecl(C);
6217 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6218 QT = MD->getObjCDeclQualifier();
6219 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6220 QT = PD->getObjCDeclQualifier();
6221 if (QT == Decl::OBJC_TQ_None)
6222 return CXObjCDeclQualifier_None;
6223
6224 unsigned Result = CXObjCDeclQualifier_None;
6225 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6226 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6227 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6228 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6229 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6230 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6231
6232 return Result;
6233}
6234
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006235unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6236 if (!clang_isDeclaration(C.kind))
6237 return 0;
6238
6239 const Decl *D = getCursorDecl(C);
6240 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6241 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6242 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6243 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6244
6245 return 0;
6246}
6247
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006248unsigned clang_Cursor_isVariadic(CXCursor C) {
6249 if (!clang_isDeclaration(C.kind))
6250 return 0;
6251
6252 const Decl *D = getCursorDecl(C);
6253 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6254 return FD->isVariadic();
6255 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6256 return MD->isVariadic();
6257
6258 return 0;
6259}
6260
Guy Benyei11169dd2012-12-18 14:30:41 +00006261CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6262 if (!clang_isDeclaration(C.kind))
6263 return clang_getNullRange();
6264
6265 const Decl *D = getCursorDecl(C);
6266 ASTContext &Context = getCursorContext(C);
6267 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6268 if (!RC)
6269 return clang_getNullRange();
6270
6271 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6272}
6273
6274CXString clang_Cursor_getRawCommentText(CXCursor C) {
6275 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006276 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006277
6278 const Decl *D = getCursorDecl(C);
6279 ASTContext &Context = getCursorContext(C);
6280 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6281 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6282 StringRef();
6283
6284 // Don't duplicate the string because RawText points directly into source
6285 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006286 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006287}
6288
6289CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6290 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006291 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006292
6293 const Decl *D = getCursorDecl(C);
6294 const ASTContext &Context = getCursorContext(C);
6295 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6296
6297 if (RC) {
6298 StringRef BriefText = RC->getBriefText(Context);
6299
6300 // Don't duplicate the string because RawComment ensures that this memory
6301 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006302 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006303 }
6304
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006305 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006306}
6307
6308CXComment clang_Cursor_getParsedComment(CXCursor C) {
6309 if (!clang_isDeclaration(C.kind))
6310 return cxcomment::createCXComment(NULL, NULL);
6311
6312 const Decl *D = getCursorDecl(C);
6313 const ASTContext &Context = getCursorContext(C);
6314 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6315
6316 return cxcomment::createCXComment(FC, getCursorTU(C));
6317}
6318
6319CXModule clang_Cursor_getModule(CXCursor C) {
6320 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006321 if (const ImportDecl *ImportD =
6322 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006323 return ImportD->getImportedModule();
6324 }
6325
6326 return 0;
6327}
6328
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006329CXFile clang_Module_getASTFile(CXModule CXMod) {
6330 if (!CXMod)
6331 return 0;
6332 Module *Mod = static_cast<Module*>(CXMod);
6333 return const_cast<FileEntry *>(Mod->getASTFile());
6334}
6335
Guy Benyei11169dd2012-12-18 14:30:41 +00006336CXModule clang_Module_getParent(CXModule CXMod) {
6337 if (!CXMod)
6338 return 0;
6339 Module *Mod = static_cast<Module*>(CXMod);
6340 return Mod->Parent;
6341}
6342
6343CXString clang_Module_getName(CXModule CXMod) {
6344 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006345 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006346 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006347 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006348}
6349
6350CXString clang_Module_getFullName(CXModule CXMod) {
6351 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006352 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006353 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006354 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006355}
6356
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006357unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6358 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006359 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006360 LOG_BAD_TU(TU);
6361 return 0;
6362 }
6363 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006364 return 0;
6365 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006366 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6367 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6368 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006369}
6370
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006371CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6372 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006373 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006374 LOG_BAD_TU(TU);
6375 return 0;
6376 }
6377 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006378 return 0;
6379 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006380 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006381
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006382 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6383 if (Index < TopHeaders.size())
6384 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006385
6386 return 0;
6387}
6388
6389} // end: extern "C"
6390
6391//===----------------------------------------------------------------------===//
6392// C++ AST instrospection.
6393//===----------------------------------------------------------------------===//
6394
6395extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006396unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6397 if (!clang_isDeclaration(C.kind))
6398 return 0;
6399
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006400 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006401 const CXXMethodDecl *Method =
6402 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006403 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6404}
6405
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006406unsigned clang_CXXMethod_isConst(CXCursor C) {
6407 if (!clang_isDeclaration(C.kind))
6408 return 0;
6409
6410 const Decl *D = cxcursor::getCursorDecl(C);
6411 const CXXMethodDecl *Method =
6412 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
6413 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6414}
6415
Guy Benyei11169dd2012-12-18 14:30:41 +00006416unsigned clang_CXXMethod_isStatic(CXCursor C) {
6417 if (!clang_isDeclaration(C.kind))
6418 return 0;
6419
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006420 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006421 const CXXMethodDecl *Method =
6422 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006423 return (Method && Method->isStatic()) ? 1 : 0;
6424}
6425
6426unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6427 if (!clang_isDeclaration(C.kind))
6428 return 0;
6429
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006430 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006431 const CXXMethodDecl *Method =
6432 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006433 return (Method && Method->isVirtual()) ? 1 : 0;
6434}
6435} // end: extern "C"
6436
6437//===----------------------------------------------------------------------===//
6438// Attribute introspection.
6439//===----------------------------------------------------------------------===//
6440
6441extern "C" {
6442CXType clang_getIBOutletCollectionType(CXCursor C) {
6443 if (C.kind != CXCursor_IBOutletCollectionAttr)
6444 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6445
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006446 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006447 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6448
6449 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6450}
6451} // end: extern "C"
6452
6453//===----------------------------------------------------------------------===//
6454// Inspecting memory usage.
6455//===----------------------------------------------------------------------===//
6456
6457typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6458
6459static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6460 enum CXTUResourceUsageKind k,
6461 unsigned long amount) {
6462 CXTUResourceUsageEntry entry = { k, amount };
6463 entries.push_back(entry);
6464}
6465
6466extern "C" {
6467
6468const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6469 const char *str = "";
6470 switch (kind) {
6471 case CXTUResourceUsage_AST:
6472 str = "ASTContext: expressions, declarations, and types";
6473 break;
6474 case CXTUResourceUsage_Identifiers:
6475 str = "ASTContext: identifiers";
6476 break;
6477 case CXTUResourceUsage_Selectors:
6478 str = "ASTContext: selectors";
6479 break;
6480 case CXTUResourceUsage_GlobalCompletionResults:
6481 str = "Code completion: cached global results";
6482 break;
6483 case CXTUResourceUsage_SourceManagerContentCache:
6484 str = "SourceManager: content cache allocator";
6485 break;
6486 case CXTUResourceUsage_AST_SideTables:
6487 str = "ASTContext: side tables";
6488 break;
6489 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6490 str = "SourceManager: malloc'ed memory buffers";
6491 break;
6492 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6493 str = "SourceManager: mmap'ed memory buffers";
6494 break;
6495 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6496 str = "ExternalASTSource: malloc'ed memory buffers";
6497 break;
6498 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6499 str = "ExternalASTSource: mmap'ed memory buffers";
6500 break;
6501 case CXTUResourceUsage_Preprocessor:
6502 str = "Preprocessor: malloc'ed memory";
6503 break;
6504 case CXTUResourceUsage_PreprocessingRecord:
6505 str = "Preprocessor: PreprocessingRecord";
6506 break;
6507 case CXTUResourceUsage_SourceManager_DataStructures:
6508 str = "SourceManager: data structures and tables";
6509 break;
6510 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6511 str = "Preprocessor: header search tables";
6512 break;
6513 }
6514 return str;
6515}
6516
6517CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006518 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006519 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006520 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6521 return usage;
6522 }
6523
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006524 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006525 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006526 ASTContext &astContext = astUnit->getASTContext();
6527
6528 // How much memory is used by AST nodes and types?
6529 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6530 (unsigned long) astContext.getASTAllocatedMemory());
6531
6532 // How much memory is used by identifiers?
6533 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6534 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6535
6536 // How much memory is used for selectors?
6537 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6538 (unsigned long) astContext.Selectors.getTotalMemory());
6539
6540 // How much memory is used by ASTContext's side tables?
6541 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6542 (unsigned long) astContext.getSideTableAllocatedMemory());
6543
6544 // How much memory is used for caching global code completion results?
6545 unsigned long completionBytes = 0;
6546 if (GlobalCodeCompletionAllocator *completionAllocator =
6547 astUnit->getCachedCompletionAllocator().getPtr()) {
6548 completionBytes = completionAllocator->getTotalMemory();
6549 }
6550 createCXTUResourceUsageEntry(*entries,
6551 CXTUResourceUsage_GlobalCompletionResults,
6552 completionBytes);
6553
6554 // How much memory is being used by SourceManager's content cache?
6555 createCXTUResourceUsageEntry(*entries,
6556 CXTUResourceUsage_SourceManagerContentCache,
6557 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6558
6559 // How much memory is being used by the MemoryBuffer's in SourceManager?
6560 const SourceManager::MemoryBufferSizes &srcBufs =
6561 astUnit->getSourceManager().getMemoryBufferSizes();
6562
6563 createCXTUResourceUsageEntry(*entries,
6564 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6565 (unsigned long) srcBufs.malloc_bytes);
6566 createCXTUResourceUsageEntry(*entries,
6567 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6568 (unsigned long) srcBufs.mmap_bytes);
6569 createCXTUResourceUsageEntry(*entries,
6570 CXTUResourceUsage_SourceManager_DataStructures,
6571 (unsigned long) astContext.getSourceManager()
6572 .getDataStructureSizes());
6573
6574 // How much memory is being used by the ExternalASTSource?
6575 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6576 const ExternalASTSource::MemoryBufferSizes &sizes =
6577 esrc->getMemoryBufferSizes();
6578
6579 createCXTUResourceUsageEntry(*entries,
6580 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6581 (unsigned long) sizes.malloc_bytes);
6582 createCXTUResourceUsageEntry(*entries,
6583 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6584 (unsigned long) sizes.mmap_bytes);
6585 }
6586
6587 // How much memory is being used by the Preprocessor?
6588 Preprocessor &pp = astUnit->getPreprocessor();
6589 createCXTUResourceUsageEntry(*entries,
6590 CXTUResourceUsage_Preprocessor,
6591 pp.getTotalMemory());
6592
6593 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6594 createCXTUResourceUsageEntry(*entries,
6595 CXTUResourceUsage_PreprocessingRecord,
6596 pRec->getTotalMemory());
6597 }
6598
6599 createCXTUResourceUsageEntry(*entries,
6600 CXTUResourceUsage_Preprocessor_HeaderSearch,
6601 pp.getHeaderSearchInfo().getTotalMemory());
6602
6603 CXTUResourceUsage usage = { (void*) entries.get(),
6604 (unsigned) entries->size(),
6605 entries->size() ? &(*entries)[0] : 0 };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006606 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006607 return usage;
6608}
6609
6610void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6611 if (usage.data)
6612 delete (MemUsageEntries*) usage.data;
6613}
6614
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006615CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6616 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006617 skipped->count = 0;
6618 skipped->ranges = 0;
6619
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006620 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006621 LOG_BAD_TU(TU);
6622 return skipped;
6623 }
6624
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006625 if (!file)
6626 return skipped;
6627
6628 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6629 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6630 if (!ppRec)
6631 return skipped;
6632
6633 ASTContext &Ctx = astUnit->getASTContext();
6634 SourceManager &sm = Ctx.getSourceManager();
6635 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6636 FileID wantedFileID = sm.translateFile(fileEntry);
6637
6638 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6639 std::vector<SourceRange> wantedRanges;
6640 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6641 i != ei; ++i) {
6642 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6643 wantedRanges.push_back(*i);
6644 }
6645
6646 skipped->count = wantedRanges.size();
6647 skipped->ranges = new CXSourceRange[skipped->count];
6648 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6649 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6650
6651 return skipped;
6652}
6653
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006654void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6655 if (ranges) {
6656 delete[] ranges->ranges;
6657 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006658 }
6659}
6660
Guy Benyei11169dd2012-12-18 14:30:41 +00006661} // end extern "C"
6662
6663void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6664 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6665 for (unsigned I = 0; I != Usage.numEntries; ++I)
6666 fprintf(stderr, " %s: %lu\n",
6667 clang_getTUResourceUsageName(Usage.entries[I].kind),
6668 Usage.entries[I].amount);
6669
6670 clang_disposeCXTUResourceUsage(Usage);
6671}
6672
6673//===----------------------------------------------------------------------===//
6674// Misc. utility functions.
6675//===----------------------------------------------------------------------===//
6676
6677/// Default to using an 8 MB stack size on "safety" threads.
6678static unsigned SafetyStackThreadSize = 8 << 20;
6679
6680namespace clang {
6681
6682bool RunSafely(llvm::CrashRecoveryContext &CRC,
6683 void (*Fn)(void*), void *UserData,
6684 unsigned Size) {
6685 if (!Size)
6686 Size = GetSafetyThreadStackSize();
6687 if (Size)
6688 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6689 return CRC.RunSafely(Fn, UserData);
6690}
6691
6692unsigned GetSafetyThreadStackSize() {
6693 return SafetyStackThreadSize;
6694}
6695
6696void SetSafetyThreadStackSize(unsigned Value) {
6697 SafetyStackThreadSize = Value;
6698}
6699
6700}
6701
6702void clang::setThreadBackgroundPriority() {
6703 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6704 return;
6705
6706 // FIXME: Move to llvm/Support and make it cross-platform.
6707#ifdef __APPLE__
6708 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6709#endif
6710}
6711
6712void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6713 if (!Unit)
6714 return;
6715
6716 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6717 DEnd = Unit->stored_diag_end();
6718 D != DEnd; ++D) {
6719 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6720 CXString Msg = clang_formatDiagnostic(&Diag,
6721 clang_defaultDiagnosticDisplayOptions());
6722 fprintf(stderr, "%s\n", clang_getCString(Msg));
6723 clang_disposeString(Msg);
6724 }
6725#ifdef LLVM_ON_WIN32
6726 // On Windows, force a flush, since there may be multiple copies of
6727 // stderr and stdout in the file system, all with different buffers
6728 // but writing to the same device.
6729 fflush(stderr);
6730#endif
6731}
6732
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006733MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6734 SourceLocation MacroDefLoc,
6735 CXTranslationUnit TU){
6736 if (MacroDefLoc.isInvalid() || !TU)
6737 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006738 if (!II.hadMacroDefinition())
6739 return 0;
6740
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006741 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006742 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006743 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006744 if (MD) {
6745 for (MacroDirective::DefInfo
6746 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6747 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6748 return Def.getMacroInfo();
6749 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006750 }
6751
6752 return 0;
6753}
6754
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006755const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6756 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006757 if (!MacroDef || !TU)
6758 return 0;
6759 const IdentifierInfo *II = MacroDef->getName();
6760 if (!II)
6761 return 0;
6762
6763 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6764}
6765
6766MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6767 const Token &Tok,
6768 CXTranslationUnit TU) {
6769 if (!MI || !TU)
6770 return 0;
6771 if (Tok.isNot(tok::raw_identifier))
6772 return 0;
6773
6774 if (MI->getNumTokens() == 0)
6775 return 0;
6776 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6777 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006778 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006779
6780 // Check that the token is inside the definition and not its argument list.
6781 SourceManager &SM = Unit->getSourceManager();
6782 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6783 return 0;
6784 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6785 return 0;
6786
6787 Preprocessor &PP = Unit->getPreprocessor();
6788 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6789 if (!PPRec)
6790 return 0;
6791
6792 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6793 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6794 if (!II.hadMacroDefinition())
6795 return 0;
6796
6797 // Check that the identifier is not one of the macro arguments.
6798 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6799 return 0;
6800
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006801 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6802 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006803 return 0;
6804
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006805 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006806}
6807
6808MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6809 SourceLocation Loc,
6810 CXTranslationUnit TU) {
6811 if (Loc.isInvalid() || !MI || !TU)
6812 return 0;
6813
6814 if (MI->getNumTokens() == 0)
6815 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006816 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006817 Preprocessor &PP = Unit->getPreprocessor();
6818 if (!PP.getPreprocessingRecord())
6819 return 0;
6820 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6821 Token Tok;
6822 if (PP.getRawToken(Loc, Tok))
6823 return 0;
6824
6825 return checkForMacroInMacroDefinition(MI, Tok, TU);
6826}
6827
Guy Benyei11169dd2012-12-18 14:30:41 +00006828extern "C" {
6829
6830CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006831 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006832}
6833
6834} // end: extern "C"
6835
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006836Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6837 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006838 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006839 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006840 if (Unit->isMainFileAST())
6841 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006842 return *this;
6843 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006844 } else {
6845 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006846 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006847 return *this;
6848}
6849
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006850Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6851 *this << FE->getName();
6852 return *this;
6853}
6854
6855Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6856 CXString cursorName = clang_getCursorDisplayName(cursor);
6857 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6858 clang_disposeString(cursorName);
6859 return *this;
6860}
6861
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006862Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6863 CXFile File;
6864 unsigned Line, Column;
6865 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6866 CXString FileName = clang_getFileName(File);
6867 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6868 clang_disposeString(FileName);
6869 return *this;
6870}
6871
6872Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6873 CXSourceLocation BLoc = clang_getRangeStart(range);
6874 CXSourceLocation ELoc = clang_getRangeEnd(range);
6875
6876 CXFile BFile;
6877 unsigned BLine, BColumn;
6878 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6879
6880 CXFile EFile;
6881 unsigned ELine, EColumn;
6882 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6883
6884 CXString BFileName = clang_getFileName(BFile);
6885 if (BFile == EFile) {
6886 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6887 BLine, BColumn, ELine, EColumn);
6888 } else {
6889 CXString EFileName = clang_getFileName(EFile);
6890 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6891 BLine, BColumn)
6892 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6893 ELine, EColumn);
6894 clang_disposeString(EFileName);
6895 }
6896 clang_disposeString(BFileName);
6897 return *this;
6898}
6899
6900Logger &cxindex::Logger::operator<<(CXString Str) {
6901 *this << clang_getCString(Str);
6902 return *this;
6903}
6904
6905Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6906 LogOS << Fmt;
6907 return *this;
6908}
6909
6910cxindex::Logger::~Logger() {
6911 LogOS.flush();
6912
6913 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6914
6915 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6916
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006917 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006918 OS << "[libclang:" << Name << ':';
6919
6920 // FIXME: Portability.
6921#if HAVE_PTHREAD_H && __APPLE__
6922 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6923 OS << tid << ':';
6924#endif
6925
6926 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6927 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6928 OS << Msg.str() << '\n';
6929
6930 if (Trace) {
6931 llvm::sys::PrintStackTrace(stderr);
6932 OS << "--------------------------------------------------\n";
6933 }
6934}