blob: 1c24e6b7b27373c746acea652b4f9502af4c6f31 [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
765/// \brief Compare two base or member initializers based on their source order.
Benjamin Kramer04bf1872013-09-22 14:10:29 +0000766static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
767 CXXCtorInitializer *const *Y) {
768 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
Guy Benyei11169dd2012-12-18 14:30:41 +0000769}
770
771bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000772 unsigned NumParamList = ND->getNumTemplateParameterLists();
773 for (unsigned i = 0; i < NumParamList; i++) {
774 TemplateParameterList* Params = ND->getTemplateParameterList(i);
775 if (VisitTemplateParameters(Params))
776 return true;
777 }
778
Guy Benyei11169dd2012-12-18 14:30:41 +0000779 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
780 // Visit the function declaration's syntactic components in the order
781 // written. This requires a bit of work.
782 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000783 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000784
785 // If we have a function declared directly (without the use of a typedef),
786 // visit just the return type. Otherwise, just visit the function's type
787 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000788 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000789 (!FTL && Visit(TL)))
790 return true;
791
792 // Visit the nested-name-specifier, if present.
793 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
794 if (VisitNestedNameSpecifierLoc(QualifierLoc))
795 return true;
796
797 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000798 if (!isa<CXXDestructorDecl>(ND))
799 if (VisitDeclarationNameInfo(ND->getNameInfo()))
800 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000801
802 // FIXME: Visit explicitly-specified template arguments!
803
804 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000805 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000806 return true;
807
Bill Wendling44426052012-12-20 19:22:21 +0000808 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000809 }
810
811 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
812 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
813 // Find the initializers that were written in the source.
814 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
815 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
816 IEnd = Constructor->init_end();
817 I != IEnd; ++I) {
818 if (!(*I)->isWritten())
819 continue;
820
821 WrittenInits.push_back(*I);
822 }
823
824 // Sort the initializers in source order
825 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
826 &CompareCXXCtorInitializers);
827
828 // Visit the initializers in source order
829 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
830 CXXCtorInitializer *Init = WrittenInits[I];
831 if (Init->isAnyMemberInitializer()) {
832 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
833 Init->getMemberLocation(), TU)))
834 return true;
835 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
836 if (Visit(TInfo->getTypeLoc()))
837 return true;
838 }
839
840 // Visit the initializer value.
841 if (Expr *Initializer = Init->getInit())
842 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
843 return true;
844 }
845 }
846
847 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
848 return true;
849 }
850
851 return false;
852}
853
854bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
855 if (VisitDeclaratorDecl(D))
856 return true;
857
858 if (Expr *BitWidth = D->getBitWidth())
859 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
860
861 return false;
862}
863
864bool CursorVisitor::VisitVarDecl(VarDecl *D) {
865 if (VisitDeclaratorDecl(D))
866 return true;
867
868 if (Expr *Init = D->getInit())
869 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
870
871 return false;
872}
873
874bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
875 if (VisitDeclaratorDecl(D))
876 return true;
877
878 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
879 if (Expr *DefArg = D->getDefaultArgument())
880 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
881
882 return false;
883}
884
885bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
886 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
887 // before visiting these template parameters.
888 if (VisitTemplateParameters(D->getTemplateParameters()))
889 return true;
890
891 return VisitFunctionDecl(D->getTemplatedDecl());
892}
893
894bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
895 // FIXME: Visit the "outer" template parameter lists on the TagDecl
896 // before visiting these template parameters.
897 if (VisitTemplateParameters(D->getTemplateParameters()))
898 return true;
899
900 return VisitCXXRecordDecl(D->getTemplatedDecl());
901}
902
903bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
904 if (VisitTemplateParameters(D->getTemplateParameters()))
905 return true;
906
907 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
908 VisitTemplateArgumentLoc(D->getDefaultArgument()))
909 return true;
910
911 return false;
912}
913
914bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000915 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000916 if (Visit(TSInfo->getTypeLoc()))
917 return true;
918
919 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
920 PEnd = ND->param_end();
921 P != PEnd; ++P) {
922 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
923 return true;
924 }
925
926 if (ND->isThisDeclarationADefinition() &&
927 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
928 return true;
929
930 return false;
931}
932
933template <typename DeclIt>
934static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
935 SourceManager &SM, SourceLocation EndLoc,
936 SmallVectorImpl<Decl *> &Decls) {
937 DeclIt next = *DI_current;
938 while (++next != DE_current) {
939 Decl *D_next = *next;
940 if (!D_next)
941 break;
942 SourceLocation L = D_next->getLocStart();
943 if (!L.isValid())
944 break;
945 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
946 *DI_current = next;
947 Decls.push_back(D_next);
948 continue;
949 }
950 break;
951 }
952}
953
Guy Benyei11169dd2012-12-18 14:30:41 +0000954bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
955 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
956 // an @implementation can lexically contain Decls that are not properly
957 // nested in the AST. When we identify such cases, we need to retrofit
958 // this nesting here.
959 if (!DI_current && !FileDI_current)
960 return VisitDeclContext(D);
961
962 // Scan the Decls that immediately come after the container
963 // in the current DeclContext. If any fall within the
964 // container's lexical region, stash them into a vector
965 // for later processing.
966 SmallVector<Decl *, 24> DeclsInContainer;
967 SourceLocation EndLoc = D->getSourceRange().getEnd();
968 SourceManager &SM = AU->getSourceManager();
969 if (EndLoc.isValid()) {
970 if (DI_current) {
971 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
972 DeclsInContainer);
973 } else {
974 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
975 DeclsInContainer);
976 }
977 }
978
979 // The common case.
980 if (DeclsInContainer.empty())
981 return VisitDeclContext(D);
982
983 // Get all the Decls in the DeclContext, and sort them with the
984 // additional ones we've collected. Then visit them.
985 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
986 I!=E; ++I) {
987 Decl *subDecl = *I;
988 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
989 subDecl->getLocStart().isInvalid())
990 continue;
991 DeclsInContainer.push_back(subDecl);
992 }
993
994 // Now sort the Decls so that they appear in lexical order.
995 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000996 [&SM](Decl *A, Decl *B) {
997 SourceLocation L_A = A->getLocStart();
998 SourceLocation L_B = B->getLocStart();
999 assert(L_A.isValid() && L_B.isValid());
1000 return SM.isBeforeInTranslationUnit(L_A, L_B);
1001 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001002
1003 // Now visit the decls.
1004 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1005 E = DeclsInContainer.end(); I != E; ++I) {
1006 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001007 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001008 if (!V.hasValue())
1009 continue;
1010 if (!V.getValue())
1011 return false;
1012 if (Visit(Cursor, true))
1013 return true;
1014 }
1015 return false;
1016}
1017
1018bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1019 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1020 TU)))
1021 return true;
1022
1023 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1024 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1025 E = ND->protocol_end(); I != E; ++I, ++PL)
1026 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1027 return true;
1028
1029 return VisitObjCContainerDecl(ND);
1030}
1031
1032bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1033 if (!PID->isThisDeclarationADefinition())
1034 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1035
1036 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1037 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1038 E = PID->protocol_end(); I != E; ++I, ++PL)
1039 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1040 return true;
1041
1042 return VisitObjCContainerDecl(PID);
1043}
1044
1045bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1046 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1047 return true;
1048
1049 // FIXME: This implements a workaround with @property declarations also being
1050 // installed in the DeclContext for the @interface. Eventually this code
1051 // should be removed.
1052 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1053 if (!CDecl || !CDecl->IsClassExtension())
1054 return false;
1055
1056 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1057 if (!ID)
1058 return false;
1059
1060 IdentifierInfo *PropertyId = PD->getIdentifier();
1061 ObjCPropertyDecl *prevDecl =
1062 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1063
1064 if (!prevDecl)
1065 return false;
1066
1067 // Visit synthesized methods since they will be skipped when visiting
1068 // the @interface.
1069 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1070 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1071 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1072 return true;
1073
1074 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1075 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1076 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1077 return true;
1078
1079 return false;
1080}
1081
1082bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1083 if (!D->isThisDeclarationADefinition()) {
1084 // Forward declaration is treated like a reference.
1085 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1086 }
1087
1088 // Issue callbacks for super class.
1089 if (D->getSuperClass() &&
1090 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1091 D->getSuperClassLoc(),
1092 TU)))
1093 return true;
1094
1095 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1096 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1097 E = D->protocol_end(); I != E; ++I, ++PL)
1098 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1099 return true;
1100
1101 return VisitObjCContainerDecl(D);
1102}
1103
1104bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1105 return VisitObjCContainerDecl(D);
1106}
1107
1108bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1109 // 'ID' could be null when dealing with invalid code.
1110 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1111 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1112 return true;
1113
1114 return VisitObjCImplDecl(D);
1115}
1116
1117bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1118#if 0
1119 // Issue callbacks for super class.
1120 // FIXME: No source location information!
1121 if (D->getSuperClass() &&
1122 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1123 D->getSuperClassLoc(),
1124 TU)))
1125 return true;
1126#endif
1127
1128 return VisitObjCImplDecl(D);
1129}
1130
1131bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1132 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1133 if (PD->isIvarNameSpecified())
1134 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1135
1136 return false;
1137}
1138
1139bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1140 return VisitDeclContext(D);
1141}
1142
1143bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1144 // Visit nested-name-specifier.
1145 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1146 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1147 return true;
1148
1149 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1150 D->getTargetNameLoc(), TU));
1151}
1152
1153bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1154 // Visit nested-name-specifier.
1155 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1156 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1157 return true;
1158 }
1159
1160 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1161 return true;
1162
1163 return VisitDeclarationNameInfo(D->getNameInfo());
1164}
1165
1166bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1167 // Visit nested-name-specifier.
1168 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1169 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1170 return true;
1171
1172 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1173 D->getIdentLocation(), TU));
1174}
1175
1176bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1177 // Visit nested-name-specifier.
1178 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1179 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1180 return true;
1181 }
1182
1183 return VisitDeclarationNameInfo(D->getNameInfo());
1184}
1185
1186bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1187 UnresolvedUsingTypenameDecl *D) {
1188 // Visit nested-name-specifier.
1189 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1190 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1191 return true;
1192
1193 return false;
1194}
1195
1196bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1197 switch (Name.getName().getNameKind()) {
1198 case clang::DeclarationName::Identifier:
1199 case clang::DeclarationName::CXXLiteralOperatorName:
1200 case clang::DeclarationName::CXXOperatorName:
1201 case clang::DeclarationName::CXXUsingDirective:
1202 return false;
1203
1204 case clang::DeclarationName::CXXConstructorName:
1205 case clang::DeclarationName::CXXDestructorName:
1206 case clang::DeclarationName::CXXConversionFunctionName:
1207 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1208 return Visit(TSInfo->getTypeLoc());
1209 return false;
1210
1211 case clang::DeclarationName::ObjCZeroArgSelector:
1212 case clang::DeclarationName::ObjCOneArgSelector:
1213 case clang::DeclarationName::ObjCMultiArgSelector:
1214 // FIXME: Per-identifier location info?
1215 return false;
1216 }
1217
1218 llvm_unreachable("Invalid DeclarationName::Kind!");
1219}
1220
1221bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1222 SourceRange Range) {
1223 // FIXME: This whole routine is a hack to work around the lack of proper
1224 // source information in nested-name-specifiers (PR5791). Since we do have
1225 // a beginning source location, we can visit the first component of the
1226 // nested-name-specifier, if it's a single-token component.
1227 if (!NNS)
1228 return false;
1229
1230 // Get the first component in the nested-name-specifier.
1231 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1232 NNS = Prefix;
1233
1234 switch (NNS->getKind()) {
1235 case NestedNameSpecifier::Namespace:
1236 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1237 TU));
1238
1239 case NestedNameSpecifier::NamespaceAlias:
1240 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1241 Range.getBegin(), TU));
1242
1243 case NestedNameSpecifier::TypeSpec: {
1244 // If the type has a form where we know that the beginning of the source
1245 // range matches up with a reference cursor. Visit the appropriate reference
1246 // cursor.
1247 const Type *T = NNS->getAsType();
1248 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1249 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1250 if (const TagType *Tag = dyn_cast<TagType>(T))
1251 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1252 if (const TemplateSpecializationType *TST
1253 = dyn_cast<TemplateSpecializationType>(T))
1254 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1255 break;
1256 }
1257
1258 case NestedNameSpecifier::TypeSpecWithTemplate:
1259 case NestedNameSpecifier::Global:
1260 case NestedNameSpecifier::Identifier:
1261 break;
1262 }
1263
1264 return false;
1265}
1266
1267bool
1268CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1269 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1270 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1271 Qualifiers.push_back(Qualifier);
1272
1273 while (!Qualifiers.empty()) {
1274 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1275 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1276 switch (NNS->getKind()) {
1277 case NestedNameSpecifier::Namespace:
1278 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1279 Q.getLocalBeginLoc(),
1280 TU)))
1281 return true;
1282
1283 break;
1284
1285 case NestedNameSpecifier::NamespaceAlias:
1286 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1287 Q.getLocalBeginLoc(),
1288 TU)))
1289 return true;
1290
1291 break;
1292
1293 case NestedNameSpecifier::TypeSpec:
1294 case NestedNameSpecifier::TypeSpecWithTemplate:
1295 if (Visit(Q.getTypeLoc()))
1296 return true;
1297
1298 break;
1299
1300 case NestedNameSpecifier::Global:
1301 case NestedNameSpecifier::Identifier:
1302 break;
1303 }
1304 }
1305
1306 return false;
1307}
1308
1309bool CursorVisitor::VisitTemplateParameters(
1310 const TemplateParameterList *Params) {
1311 if (!Params)
1312 return false;
1313
1314 for (TemplateParameterList::const_iterator P = Params->begin(),
1315 PEnd = Params->end();
1316 P != PEnd; ++P) {
1317 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1318 return true;
1319 }
1320
1321 return false;
1322}
1323
1324bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1325 switch (Name.getKind()) {
1326 case TemplateName::Template:
1327 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1328
1329 case TemplateName::OverloadedTemplate:
1330 // Visit the overloaded template set.
1331 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1332 return true;
1333
1334 return false;
1335
1336 case TemplateName::DependentTemplate:
1337 // FIXME: Visit nested-name-specifier.
1338 return false;
1339
1340 case TemplateName::QualifiedTemplate:
1341 // FIXME: Visit nested-name-specifier.
1342 return Visit(MakeCursorTemplateRef(
1343 Name.getAsQualifiedTemplateName()->getDecl(),
1344 Loc, TU));
1345
1346 case TemplateName::SubstTemplateTemplateParm:
1347 return Visit(MakeCursorTemplateRef(
1348 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1349 Loc, TU));
1350
1351 case TemplateName::SubstTemplateTemplateParmPack:
1352 return Visit(MakeCursorTemplateRef(
1353 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1354 Loc, TU));
1355 }
1356
1357 llvm_unreachable("Invalid TemplateName::Kind!");
1358}
1359
1360bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1361 switch (TAL.getArgument().getKind()) {
1362 case TemplateArgument::Null:
1363 case TemplateArgument::Integral:
1364 case TemplateArgument::Pack:
1365 return false;
1366
1367 case TemplateArgument::Type:
1368 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1369 return Visit(TSInfo->getTypeLoc());
1370 return false;
1371
1372 case TemplateArgument::Declaration:
1373 if (Expr *E = TAL.getSourceDeclExpression())
1374 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1375 return false;
1376
1377 case TemplateArgument::NullPtr:
1378 if (Expr *E = TAL.getSourceNullPtrExpression())
1379 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1380 return false;
1381
1382 case TemplateArgument::Expression:
1383 if (Expr *E = TAL.getSourceExpression())
1384 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1385 return false;
1386
1387 case TemplateArgument::Template:
1388 case TemplateArgument::TemplateExpansion:
1389 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1390 return true;
1391
1392 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1393 TAL.getTemplateNameLoc());
1394 }
1395
1396 llvm_unreachable("Invalid TemplateArgument::Kind!");
1397}
1398
1399bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1400 return VisitDeclContext(D);
1401}
1402
1403bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1404 return Visit(TL.getUnqualifiedLoc());
1405}
1406
1407bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1408 ASTContext &Context = AU->getASTContext();
1409
1410 // Some builtin types (such as Objective-C's "id", "sel", and
1411 // "Class") have associated declarations. Create cursors for those.
1412 QualType VisitType;
1413 switch (TL.getTypePtr()->getKind()) {
1414
1415 case BuiltinType::Void:
1416 case BuiltinType::NullPtr:
1417 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001418 case BuiltinType::OCLImage1d:
1419 case BuiltinType::OCLImage1dArray:
1420 case BuiltinType::OCLImage1dBuffer:
1421 case BuiltinType::OCLImage2d:
1422 case BuiltinType::OCLImage2dArray:
1423 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001424 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001425 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001426#define BUILTIN_TYPE(Id, SingletonId)
1427#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1428#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1429#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1430#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1431#include "clang/AST/BuiltinTypes.def"
1432 break;
1433
1434 case BuiltinType::ObjCId:
1435 VisitType = Context.getObjCIdType();
1436 break;
1437
1438 case BuiltinType::ObjCClass:
1439 VisitType = Context.getObjCClassType();
1440 break;
1441
1442 case BuiltinType::ObjCSel:
1443 VisitType = Context.getObjCSelType();
1444 break;
1445 }
1446
1447 if (!VisitType.isNull()) {
1448 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1449 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1450 TU));
1451 }
1452
1453 return false;
1454}
1455
1456bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1457 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1458}
1459
1460bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1461 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1462}
1463
1464bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1465 if (TL.isDefinition())
1466 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1467
1468 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1469}
1470
1471bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1472 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1473}
1474
1475bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1476 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1477 return true;
1478
1479 return false;
1480}
1481
1482bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1483 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1484 return true;
1485
1486 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1487 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1488 TU)))
1489 return true;
1490 }
1491
1492 return false;
1493}
1494
1495bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1496 return Visit(TL.getPointeeLoc());
1497}
1498
1499bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1500 return Visit(TL.getInnerLoc());
1501}
1502
1503bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1504 return Visit(TL.getPointeeLoc());
1505}
1506
1507bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1508 return Visit(TL.getPointeeLoc());
1509}
1510
1511bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1512 return Visit(TL.getPointeeLoc());
1513}
1514
1515bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1516 return Visit(TL.getPointeeLoc());
1517}
1518
1519bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1520 return Visit(TL.getPointeeLoc());
1521}
1522
1523bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1524 return Visit(TL.getModifiedLoc());
1525}
1526
1527bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1528 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001529 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001530 return true;
1531
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001532 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1533 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001534 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1535 return true;
1536
1537 return false;
1538}
1539
1540bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1541 if (Visit(TL.getElementLoc()))
1542 return true;
1543
1544 if (Expr *Size = TL.getSizeExpr())
1545 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1546
1547 return false;
1548}
1549
Reid Kleckner8a365022013-06-24 17:51:48 +00001550bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1551 return Visit(TL.getOriginalLoc());
1552}
1553
Reid Kleckner0503a872013-12-05 01:23:43 +00001554bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1555 return Visit(TL.getOriginalLoc());
1556}
1557
Guy Benyei11169dd2012-12-18 14:30:41 +00001558bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1559 TemplateSpecializationTypeLoc TL) {
1560 // Visit the template name.
1561 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1562 TL.getTemplateNameLoc()))
1563 return true;
1564
1565 // Visit the template arguments.
1566 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1567 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1568 return true;
1569
1570 return false;
1571}
1572
1573bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1574 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1575}
1576
1577bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1578 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1579 return Visit(TSInfo->getTypeLoc());
1580
1581 return false;
1582}
1583
1584bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1585 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1586 return Visit(TSInfo->getTypeLoc());
1587
1588 return false;
1589}
1590
1591bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1592 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1593 return true;
1594
1595 return false;
1596}
1597
1598bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1599 DependentTemplateSpecializationTypeLoc TL) {
1600 // Visit the nested-name-specifier, if there is one.
1601 if (TL.getQualifierLoc() &&
1602 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1603 return true;
1604
1605 // Visit the template arguments.
1606 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1607 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1608 return true;
1609
1610 return false;
1611}
1612
1613bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1614 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1615 return true;
1616
1617 return Visit(TL.getNamedTypeLoc());
1618}
1619
1620bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1621 return Visit(TL.getPatternLoc());
1622}
1623
1624bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1625 if (Expr *E = TL.getUnderlyingExpr())
1626 return Visit(MakeCXCursor(E, StmtParent, TU));
1627
1628 return false;
1629}
1630
1631bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1632 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1633}
1634
1635bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1636 return Visit(TL.getValueLoc());
1637}
1638
1639#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1640bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1641 return Visit##PARENT##Loc(TL); \
1642}
1643
1644DEFAULT_TYPELOC_IMPL(Complex, Type)
1645DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1646DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1647DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1648DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1649DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1650DEFAULT_TYPELOC_IMPL(Vector, Type)
1651DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1652DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1653DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1654DEFAULT_TYPELOC_IMPL(Record, TagType)
1655DEFAULT_TYPELOC_IMPL(Enum, TagType)
1656DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1657DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1658DEFAULT_TYPELOC_IMPL(Auto, Type)
1659
1660bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1661 // Visit the nested-name-specifier, if present.
1662 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1663 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1664 return true;
1665
1666 if (D->isCompleteDefinition()) {
1667 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1668 E = D->bases_end(); I != E; ++I) {
1669 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1670 return true;
1671 }
1672 }
1673
1674 return VisitTagDecl(D);
1675}
1676
1677bool CursorVisitor::VisitAttributes(Decl *D) {
1678 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1679 i != e; ++i)
1680 if (Visit(MakeCXCursor(*i, D, TU)))
1681 return true;
1682
1683 return false;
1684}
1685
1686//===----------------------------------------------------------------------===//
1687// Data-recursive visitor methods.
1688//===----------------------------------------------------------------------===//
1689
1690namespace {
1691#define DEF_JOB(NAME, DATA, KIND)\
1692class NAME : public VisitorJob {\
1693public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001694 NAME(const DATA *d, CXCursor parent) : \
1695 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001696 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001697 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001698};
1699
1700DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1701DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1702DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1703DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1704DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1705 ExplicitTemplateArgsVisitKind)
1706DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1707DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1708DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1709#undef DEF_JOB
1710
1711class DeclVisit : public VisitorJob {
1712public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001713 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001714 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001715 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001716 static bool classof(const VisitorJob *VJ) {
1717 return VJ->getKind() == DeclVisitKind;
1718 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001719 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001720 bool isFirst() const { return data[1] ? true : false; }
1721};
1722class TypeLocVisit : public VisitorJob {
1723public:
1724 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1725 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1726 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1727
1728 static bool classof(const VisitorJob *VJ) {
1729 return VJ->getKind() == TypeLocVisitKind;
1730 }
1731
1732 TypeLoc get() const {
1733 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001734 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001735 }
1736};
1737
1738class LabelRefVisit : public VisitorJob {
1739public:
1740 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1741 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1742 labelLoc.getPtrEncoding()) {}
1743
1744 static bool classof(const VisitorJob *VJ) {
1745 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1746 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001747 const LabelDecl *get() const {
1748 return static_cast<const LabelDecl *>(data[0]);
1749 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001750 SourceLocation getLoc() const {
1751 return SourceLocation::getFromPtrEncoding(data[1]); }
1752};
1753
1754class NestedNameSpecifierLocVisit : public VisitorJob {
1755public:
1756 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1757 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1758 Qualifier.getNestedNameSpecifier(),
1759 Qualifier.getOpaqueData()) { }
1760
1761 static bool classof(const VisitorJob *VJ) {
1762 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1763 }
1764
1765 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001766 return NestedNameSpecifierLoc(
1767 const_cast<NestedNameSpecifier *>(
1768 static_cast<const NestedNameSpecifier *>(data[0])),
1769 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001770 }
1771};
1772
1773class DeclarationNameInfoVisit : public VisitorJob {
1774public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001775 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001776 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001777 static bool classof(const VisitorJob *VJ) {
1778 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1779 }
1780 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001781 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001782 switch (S->getStmtClass()) {
1783 default:
1784 llvm_unreachable("Unhandled Stmt");
1785 case clang::Stmt::MSDependentExistsStmtClass:
1786 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1787 case Stmt::CXXDependentScopeMemberExprClass:
1788 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1789 case Stmt::DependentScopeDeclRefExprClass:
1790 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1791 }
1792 }
1793};
1794class MemberRefVisit : public VisitorJob {
1795public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001796 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001797 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1798 L.getPtrEncoding()) {}
1799 static bool classof(const VisitorJob *VJ) {
1800 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1801 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001802 const FieldDecl *get() const {
1803 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001804 }
1805 SourceLocation getLoc() const {
1806 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1807 }
1808};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001809class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001810 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001811 VisitorWorkList &WL;
1812 CXCursor Parent;
1813public:
1814 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1815 : WL(wl), Parent(parent) {}
1816
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001817 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1818 void VisitBlockExpr(const BlockExpr *B);
1819 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1820 void VisitCompoundStmt(const CompoundStmt *S);
1821 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1822 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1823 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1824 void VisitCXXNewExpr(const CXXNewExpr *E);
1825 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1826 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1827 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1828 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1829 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1830 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1831 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1832 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1833 void VisitDeclRefExpr(const DeclRefExpr *D);
1834 void VisitDeclStmt(const DeclStmt *S);
1835 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1836 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1837 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1838 void VisitForStmt(const ForStmt *FS);
1839 void VisitGotoStmt(const GotoStmt *GS);
1840 void VisitIfStmt(const IfStmt *If);
1841 void VisitInitListExpr(const InitListExpr *IE);
1842 void VisitMemberExpr(const MemberExpr *M);
1843 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1844 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1845 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1846 void VisitOverloadExpr(const OverloadExpr *E);
1847 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1848 void VisitStmt(const Stmt *S);
1849 void VisitSwitchStmt(const SwitchStmt *S);
1850 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001851 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1852 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1853 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1854 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1855 void VisitVAArgExpr(const VAArgExpr *E);
1856 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1857 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1858 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1859 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001860 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1861 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001862 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001863
Guy Benyei11169dd2012-12-18 14:30:41 +00001864private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001865 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001866 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1867 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001868 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1869 void AddStmt(const Stmt *S);
1870 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001871 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001872 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001873 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001874};
1875} // end anonyous namespace
1876
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001877void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001878 // 'S' should always be non-null, since it comes from the
1879 // statement we are visiting.
1880 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1881}
1882
1883void
1884EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1885 if (Qualifier)
1886 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1887}
1888
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001889void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001890 if (S)
1891 WL.push_back(StmtVisit(S, Parent));
1892}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001893void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001894 if (D)
1895 WL.push_back(DeclVisit(D, Parent, isFirst));
1896}
1897void EnqueueVisitor::
1898 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1899 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001900 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001901}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001903 if (D)
1904 WL.push_back(MemberRefVisit(D, L, Parent));
1905}
1906void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1907 if (TI)
1908 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1909 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001910void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001911 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001912 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001913 AddStmt(*Child);
1914 }
1915 if (size == WL.size())
1916 return;
1917 // Now reverse the entries we just added. This will match the DFS
1918 // ordering performed by the worklist.
1919 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1920 std::reverse(I, E);
1921}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001922namespace {
1923class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1924 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001925 /// \brief Process clauses with list of variables.
1926 template <typename T>
1927 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001928public:
1929 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1930#define OPENMP_CLAUSE(Name, Class) \
1931 void Visit##Class(const Class *C);
1932#include "clang/Basic/OpenMPKinds.def"
1933};
1934
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001935void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1936 Visitor->AddStmt(C->getCondition());
1937}
1938
Alexey Bataev568a8332014-03-06 06:15:19 +00001939void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1940 Visitor->AddStmt(C->getNumThreads());
1941}
1942
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001943void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001944
1945template<typename T>
1946void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
1947 for (typename T::varlist_const_iterator I = Node->varlist_begin(),
1948 E = Node->varlist_end();
1949 I != E; ++I)
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001950 Visitor->AddStmt(*I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001951}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001952
1953void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001954 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001955}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001956void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1957 const OMPFirstprivateClause *C) {
1958 VisitOMPClauseList(C);
1959}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001960void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001961 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001962}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001963}
Alexey Bataev756c1962013-09-24 03:17:45 +00001964
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001965void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1966 unsigned size = WL.size();
1967 OMPClauseEnqueue Visitor(this);
1968 Visitor.Visit(S);
1969 if (size == WL.size())
1970 return;
1971 // Now reverse the entries we just added. This will match the DFS
1972 // ordering performed by the worklist.
1973 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1974 std::reverse(I, E);
1975}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001976void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001977 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1978}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001979void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001980 AddDecl(B->getBlockDecl());
1981}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001982void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001983 EnqueueChildren(E);
1984 AddTypeLoc(E->getTypeSourceInfo());
1985}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001986void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1987 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001988 E = S->body_rend(); I != E; ++I) {
1989 AddStmt(*I);
1990 }
1991}
1992void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001993VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001994 AddStmt(S->getSubStmt());
1995 AddDeclarationNameInfo(S);
1996 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1997 AddNestedNameSpecifierLoc(QualifierLoc);
1998}
1999
2000void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002001VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002002 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2003 AddDeclarationNameInfo(E);
2004 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2005 AddNestedNameSpecifierLoc(QualifierLoc);
2006 if (!E->isImplicitAccess())
2007 AddStmt(E->getBase());
2008}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002009void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002010 // Enqueue the initializer , if any.
2011 AddStmt(E->getInitializer());
2012 // Enqueue the array size, if any.
2013 AddStmt(E->getArraySize());
2014 // Enqueue the allocated type.
2015 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2016 // Enqueue the placement arguments.
2017 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2018 AddStmt(E->getPlacementArg(I-1));
2019}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002020void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002021 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2022 AddStmt(CE->getArg(I-1));
2023 AddStmt(CE->getCallee());
2024 AddStmt(CE->getArg(0));
2025}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002026void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2027 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002028 // Visit the name of the type being destroyed.
2029 AddTypeLoc(E->getDestroyedTypeInfo());
2030 // Visit the scope type that looks disturbingly like the nested-name-specifier
2031 // but isn't.
2032 AddTypeLoc(E->getScopeTypeInfo());
2033 // Visit the nested-name-specifier.
2034 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2035 AddNestedNameSpecifierLoc(QualifierLoc);
2036 // Visit base expression.
2037 AddStmt(E->getBase());
2038}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002039void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2040 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002041 AddTypeLoc(E->getTypeSourceInfo());
2042}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002043void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2044 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002045 EnqueueChildren(E);
2046 AddTypeLoc(E->getTypeSourceInfo());
2047}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002048void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002049 EnqueueChildren(E);
2050 if (E->isTypeOperand())
2051 AddTypeLoc(E->getTypeOperandSourceInfo());
2052}
2053
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002054void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2055 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002056 EnqueueChildren(E);
2057 AddTypeLoc(E->getTypeSourceInfo());
2058}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002059void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002060 EnqueueChildren(E);
2061 if (E->isTypeOperand())
2062 AddTypeLoc(E->getTypeOperandSourceInfo());
2063}
2064
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002065void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002066 EnqueueChildren(S);
2067 AddDecl(S->getExceptionDecl());
2068}
2069
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002070void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002071 if (DR->hasExplicitTemplateArgs()) {
2072 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2073 }
2074 WL.push_back(DeclRefExprParts(DR, Parent));
2075}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002076void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2077 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002078 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2079 AddDeclarationNameInfo(E);
2080 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2081}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002082void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002083 unsigned size = WL.size();
2084 bool isFirst = true;
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002085 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00002086 D != DEnd; ++D) {
2087 AddDecl(*D, isFirst);
2088 isFirst = false;
2089 }
2090 if (size == WL.size())
2091 return;
2092 // Now reverse the entries we just added. This will match the DFS
2093 // ordering performed by the worklist.
2094 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2095 std::reverse(I, E);
2096}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002097void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002098 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002099 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002100 D = E->designators_rbegin(), DEnd = E->designators_rend();
2101 D != DEnd; ++D) {
2102 if (D->isFieldDesignator()) {
2103 if (FieldDecl *Field = D->getField())
2104 AddMemberRef(Field, D->getFieldLoc());
2105 continue;
2106 }
2107 if (D->isArrayDesignator()) {
2108 AddStmt(E->getArrayIndex(*D));
2109 continue;
2110 }
2111 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2112 AddStmt(E->getArrayRangeEnd(*D));
2113 AddStmt(E->getArrayRangeStart(*D));
2114 }
2115}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002116void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002117 EnqueueChildren(E);
2118 AddTypeLoc(E->getTypeInfoAsWritten());
2119}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002120void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002121 AddStmt(FS->getBody());
2122 AddStmt(FS->getInc());
2123 AddStmt(FS->getCond());
2124 AddDecl(FS->getConditionVariable());
2125 AddStmt(FS->getInit());
2126}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002127void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002128 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2129}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002130void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002131 AddStmt(If->getElse());
2132 AddStmt(If->getThen());
2133 AddStmt(If->getCond());
2134 AddDecl(If->getConditionVariable());
2135}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002136void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002137 // We care about the syntactic form of the initializer list, only.
2138 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2139 IE = Syntactic;
2140 EnqueueChildren(IE);
2141}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002142void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002143 WL.push_back(MemberExprParts(M, Parent));
2144
2145 // If the base of the member access expression is an implicit 'this', don't
2146 // visit it.
2147 // FIXME: If we ever want to show these implicit accesses, this will be
2148 // unfortunate. However, clang_getCursor() relies on this behavior.
2149 if (!M->isImplicitAccess())
2150 AddStmt(M->getBase());
2151}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002152void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002153 AddTypeLoc(E->getEncodedTypeSourceInfo());
2154}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002155void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002156 EnqueueChildren(M);
2157 AddTypeLoc(M->getClassReceiverTypeInfo());
2158}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002159void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002160 // Visit the components of the offsetof expression.
2161 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2162 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2163 const OffsetOfNode &Node = E->getComponent(I-1);
2164 switch (Node.getKind()) {
2165 case OffsetOfNode::Array:
2166 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2167 break;
2168 case OffsetOfNode::Field:
2169 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2170 break;
2171 case OffsetOfNode::Identifier:
2172 case OffsetOfNode::Base:
2173 continue;
2174 }
2175 }
2176 // Visit the type into which we're computing the offset.
2177 AddTypeLoc(E->getTypeSourceInfo());
2178}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002179void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002180 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2181 WL.push_back(OverloadExprParts(E, Parent));
2182}
2183void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002184 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002185 EnqueueChildren(E);
2186 if (E->isArgumentType())
2187 AddTypeLoc(E->getArgumentTypeInfo());
2188}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002189void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002190 EnqueueChildren(S);
2191}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002192void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002193 AddStmt(S->getBody());
2194 AddStmt(S->getCond());
2195 AddDecl(S->getConditionVariable());
2196}
2197
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002198void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002199 AddStmt(W->getBody());
2200 AddStmt(W->getCond());
2201 AddDecl(W->getConditionVariable());
2202}
2203
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002204void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002205 for (unsigned I = E->getNumArgs(); I > 0; --I)
2206 AddTypeLoc(E->getArg(I-1));
2207}
2208
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002209void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002210 AddTypeLoc(E->getQueriedTypeSourceInfo());
2211}
2212
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002213void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002214 EnqueueChildren(E);
2215}
2216
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002218 VisitOverloadExpr(U);
2219 if (!U->isImplicitAccess())
2220 AddStmt(U->getBase());
2221}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002222void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002223 AddStmt(E->getSubExpr());
2224 AddTypeLoc(E->getWrittenTypeInfo());
2225}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002226void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002227 WL.push_back(SizeOfPackExprParts(E, Parent));
2228}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002229void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002230 // If the opaque value has a source expression, just transparently
2231 // visit that. This is useful for (e.g.) pseudo-object expressions.
2232 if (Expr *SourceExpr = E->getSourceExpr())
2233 return Visit(SourceExpr);
2234}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002235void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002236 AddStmt(E->getBody());
2237 WL.push_back(LambdaExprParts(E, Parent));
2238}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002239void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002240 // Treat the expression like its syntactic form.
2241 Visit(E->getSyntacticForm());
2242}
2243
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002244void EnqueueVisitor::VisitOMPExecutableDirective(
2245 const OMPExecutableDirective *D) {
2246 EnqueueChildren(D);
2247 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2248 E = D->clauses().end();
2249 I != E; ++I)
2250 EnqueueChildren(*I);
2251}
2252
2253void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2254 VisitOMPExecutableDirective(D);
2255}
2256
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002257void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2258 VisitOMPExecutableDirective(D);
2259}
2260
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002261void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002262 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2263}
2264
2265bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2266 if (RegionOfInterest.isValid()) {
2267 SourceRange Range = getRawCursorExtent(C);
2268 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2269 return false;
2270 }
2271 return true;
2272}
2273
2274bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2275 while (!WL.empty()) {
2276 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002277 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002278
2279 // Set the Parent field, then back to its old value once we're done.
2280 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2281
2282 switch (LI.getKind()) {
2283 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002284 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002285 if (!D)
2286 continue;
2287
2288 // For now, perform default visitation for Decls.
2289 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2290 cast<DeclVisit>(&LI)->isFirst())))
2291 return true;
2292
2293 continue;
2294 }
2295 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2296 const ASTTemplateArgumentListInfo *ArgList =
2297 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2298 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2299 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2300 Arg != ArgEnd; ++Arg) {
2301 if (VisitTemplateArgumentLoc(*Arg))
2302 return true;
2303 }
2304 continue;
2305 }
2306 case VisitorJob::TypeLocVisitKind: {
2307 // Perform default visitation for TypeLocs.
2308 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2309 return true;
2310 continue;
2311 }
2312 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002313 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002314 if (LabelStmt *stmt = LS->getStmt()) {
2315 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2316 TU))) {
2317 return true;
2318 }
2319 }
2320 continue;
2321 }
2322
2323 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2324 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2325 if (VisitNestedNameSpecifierLoc(V->get()))
2326 return true;
2327 continue;
2328 }
2329
2330 case VisitorJob::DeclarationNameInfoVisitKind: {
2331 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2332 ->get()))
2333 return true;
2334 continue;
2335 }
2336 case VisitorJob::MemberRefVisitKind: {
2337 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2338 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2339 return true;
2340 continue;
2341 }
2342 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002343 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002344 if (!S)
2345 continue;
2346
2347 // Update the current cursor.
2348 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2349 if (!IsInRegionOfInterest(Cursor))
2350 continue;
2351 switch (Visitor(Cursor, Parent, ClientData)) {
2352 case CXChildVisit_Break: return true;
2353 case CXChildVisit_Continue: break;
2354 case CXChildVisit_Recurse:
2355 if (PostChildrenVisitor)
2356 WL.push_back(PostChildrenVisit(0, Cursor));
2357 EnqueueWorkList(WL, S);
2358 break;
2359 }
2360 continue;
2361 }
2362 case VisitorJob::MemberExprPartsKind: {
2363 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002364 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002365
2366 // Visit the nested-name-specifier
2367 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2368 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2369 return true;
2370
2371 // Visit the declaration name.
2372 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2373 return true;
2374
2375 // Visit the explicitly-specified template arguments, if any.
2376 if (M->hasExplicitTemplateArgs()) {
2377 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2378 *ArgEnd = Arg + M->getNumTemplateArgs();
2379 Arg != ArgEnd; ++Arg) {
2380 if (VisitTemplateArgumentLoc(*Arg))
2381 return true;
2382 }
2383 }
2384 continue;
2385 }
2386 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002387 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002388 // Visit nested-name-specifier, if present.
2389 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2390 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2391 return true;
2392 // Visit declaration name.
2393 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2394 return true;
2395 continue;
2396 }
2397 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002398 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002399 // Visit the nested-name-specifier.
2400 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2401 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2402 return true;
2403 // Visit the declaration name.
2404 if (VisitDeclarationNameInfo(O->getNameInfo()))
2405 return true;
2406 // Visit the overloaded declaration reference.
2407 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2408 return true;
2409 continue;
2410 }
2411 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002412 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002413 NamedDecl *Pack = E->getPack();
2414 if (isa<TemplateTypeParmDecl>(Pack)) {
2415 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2416 E->getPackLoc(), TU)))
2417 return true;
2418
2419 continue;
2420 }
2421
2422 if (isa<TemplateTemplateParmDecl>(Pack)) {
2423 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2424 E->getPackLoc(), TU)))
2425 return true;
2426
2427 continue;
2428 }
2429
2430 // Non-type template parameter packs and function parameter packs are
2431 // treated like DeclRefExpr cursors.
2432 continue;
2433 }
2434
2435 case VisitorJob::LambdaExprPartsKind: {
2436 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002437 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002438 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2439 CEnd = E->explicit_capture_end();
2440 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002441 // FIXME: Lambda init-captures.
2442 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002443 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002444
Guy Benyei11169dd2012-12-18 14:30:41 +00002445 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2446 C->getLocation(),
2447 TU)))
2448 return true;
2449 }
2450
2451 // Visit parameters and return type, if present.
2452 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2453 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2454 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2455 // Visit the whole type.
2456 if (Visit(TL))
2457 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002458 } else if (FunctionProtoTypeLoc Proto =
2459 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002460 if (E->hasExplicitParameters()) {
2461 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002462 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2463 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002464 return true;
2465 } else {
2466 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002467 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002468 return true;
2469 }
2470 }
2471 }
2472 break;
2473 }
2474
2475 case VisitorJob::PostChildrenVisitKind:
2476 if (PostChildrenVisitor(Parent, ClientData))
2477 return true;
2478 break;
2479 }
2480 }
2481 return false;
2482}
2483
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002484bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002485 VisitorWorkList *WL = 0;
2486 if (!WorkListFreeList.empty()) {
2487 WL = WorkListFreeList.back();
2488 WL->clear();
2489 WorkListFreeList.pop_back();
2490 }
2491 else {
2492 WL = new VisitorWorkList();
2493 WorkListCache.push_back(WL);
2494 }
2495 EnqueueWorkList(*WL, S);
2496 bool result = RunVisitorWorkList(*WL);
2497 WorkListFreeList.push_back(WL);
2498 return result;
2499}
2500
2501namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002502typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002503RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2504 const DeclarationNameInfo &NI,
2505 const SourceRange &QLoc,
2506 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2507 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2508 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2509 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2510
2511 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2512
2513 RefNamePieces Pieces;
2514
2515 if (WantQualifier && QLoc.isValid())
2516 Pieces.push_back(QLoc);
2517
2518 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2519 Pieces.push_back(NI.getLoc());
2520
2521 if (WantTemplateArgs && TemplateArgs)
2522 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2523 TemplateArgs->RAngleLoc));
2524
2525 if (Kind == DeclarationName::CXXOperatorName) {
2526 Pieces.push_back(SourceLocation::getFromRawEncoding(
2527 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2528 Pieces.push_back(SourceLocation::getFromRawEncoding(
2529 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2530 }
2531
2532 if (WantSinglePiece) {
2533 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2534 Pieces.clear();
2535 Pieces.push_back(R);
2536 }
2537
2538 return Pieces;
2539}
2540}
2541
2542//===----------------------------------------------------------------------===//
2543// Misc. API hooks.
2544//===----------------------------------------------------------------------===//
2545
2546static llvm::sys::Mutex EnableMultithreadingMutex;
2547static bool EnabledMultithreading;
2548
Chad Rosier05c71aa2013-03-27 18:28:23 +00002549static void fatal_error_handler(void *user_data, const std::string& reason,
2550 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002551 // Write the result out to stderr avoiding errs() because raw_ostreams can
2552 // call report_fatal_error.
2553 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2554 ::abort();
2555}
2556
2557extern "C" {
2558CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2559 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002560 // We use crash recovery to make some of our APIs more reliable, implicitly
2561 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002562 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2563 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002564
2565 // Enable support for multithreading in LLVM.
2566 {
2567 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2568 if (!EnabledMultithreading) {
2569 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2570 llvm::llvm_start_multithreaded();
2571 EnabledMultithreading = true;
2572 }
2573 }
2574
2575 CIndexer *CIdxr = new CIndexer();
2576 if (excludeDeclarationsFromPCH)
2577 CIdxr->setOnlyLocalDecls();
2578 if (displayDiagnostics)
2579 CIdxr->setDisplayDiagnostics();
2580
2581 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2582 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2583 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2584 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2585 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2586 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2587
2588 return CIdxr;
2589}
2590
2591void clang_disposeIndex(CXIndex CIdx) {
2592 if (CIdx)
2593 delete static_cast<CIndexer *>(CIdx);
2594}
2595
2596void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2597 if (CIdx)
2598 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2599}
2600
2601unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2602 if (CIdx)
2603 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2604 return 0;
2605}
2606
2607void clang_toggleCrashRecovery(unsigned isEnabled) {
2608 if (isEnabled)
2609 llvm::CrashRecoveryContext::Enable();
2610 else
2611 llvm::CrashRecoveryContext::Disable();
2612}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002613
Guy Benyei11169dd2012-12-18 14:30:41 +00002614CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2615 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002616 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002617 enum CXErrorCode Result =
2618 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002619 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002620 assert((TU && Result == CXError_Success) ||
2621 (!TU && Result != CXError_Success));
2622 return TU;
2623}
2624
2625enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2626 const char *ast_filename,
2627 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002628 if (out_TU)
2629 *out_TU = NULL;
2630
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002631 if (!CIdx || !ast_filename || !out_TU)
2632 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002633
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002634 LOG_FUNC_SECTION {
2635 *Log << ast_filename;
2636 }
2637
Guy Benyei11169dd2012-12-18 14:30:41 +00002638 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2639 FileSystemOptions FileSystemOpts;
2640
2641 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002642 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002643 CXXIdx->getOnlyLocalDecls(), None,
2644 /*CaptureDiagnostics=*/true,
2645 /*AllowPCHWithCompilerErrors=*/true,
2646 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002647 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2648 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002649}
2650
2651unsigned clang_defaultEditingTranslationUnitOptions() {
2652 return CXTranslationUnit_PrecompiledPreamble |
2653 CXTranslationUnit_CacheCompletionResults;
2654}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002655
Guy Benyei11169dd2012-12-18 14:30:41 +00002656CXTranslationUnit
2657clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2658 const char *source_filename,
2659 int num_command_line_args,
2660 const char * const *command_line_args,
2661 unsigned num_unsaved_files,
2662 struct CXUnsavedFile *unsaved_files) {
2663 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2664 return clang_parseTranslationUnit(CIdx, source_filename,
2665 command_line_args, num_command_line_args,
2666 unsaved_files, num_unsaved_files,
2667 Options);
2668}
2669
2670struct ParseTranslationUnitInfo {
2671 CXIndex CIdx;
2672 const char *source_filename;
2673 const char *const *command_line_args;
2674 int num_command_line_args;
2675 struct CXUnsavedFile *unsaved_files;
2676 unsigned num_unsaved_files;
2677 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002678 CXTranslationUnit *out_TU;
2679 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002680};
2681static void clang_parseTranslationUnit_Impl(void *UserData) {
2682 ParseTranslationUnitInfo *PTUI =
2683 static_cast<ParseTranslationUnitInfo*>(UserData);
2684 CXIndex CIdx = PTUI->CIdx;
2685 const char *source_filename = PTUI->source_filename;
2686 const char * const *command_line_args = PTUI->command_line_args;
2687 int num_command_line_args = PTUI->num_command_line_args;
2688 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2689 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2690 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002691 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002692
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002693 // Set up the initial return values.
2694 if (out_TU)
2695 *out_TU = NULL;
2696 PTUI->result = CXError_Failure;
2697
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002698 // Check arguments.
2699 if (!CIdx || !out_TU ||
2700 (unsaved_files == NULL && num_unsaved_files != 0)) {
2701 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002702 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002703 }
2704
Guy Benyei11169dd2012-12-18 14:30:41 +00002705 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2706
2707 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2708 setThreadBackgroundPriority();
2709
2710 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2711 // FIXME: Add a flag for modules.
2712 TranslationUnitKind TUKind
2713 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002714 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002715 = options & CXTranslationUnit_CacheCompletionResults;
2716 bool IncludeBriefCommentsInCodeCompletion
2717 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2718 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2719 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2720
2721 // Configure the diagnostics.
2722 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002723 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002724
2725 // Recover resources if we crash before exiting this function.
2726 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2727 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2728 DiagCleanup(Diags.getPtr());
2729
2730 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2731 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2732
2733 // Recover resources if we crash before exiting this function.
2734 llvm::CrashRecoveryContextCleanupRegistrar<
2735 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2736
2737 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2738 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2739 const llvm::MemoryBuffer *Buffer
2740 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2741 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2742 Buffer));
2743 }
2744
2745 OwningPtr<std::vector<const char *> >
2746 Args(new std::vector<const char*>());
2747
2748 // Recover resources if we crash before exiting this method.
2749 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2750 ArgsCleanup(Args.get());
2751
2752 // Since the Clang C library is primarily used by batch tools dealing with
2753 // (often very broken) source code, where spell-checking can have a
2754 // significant negative impact on performance (particularly when
2755 // precompiled headers are involved), we disable it by default.
2756 // Only do this if we haven't found a spell-checking-related argument.
2757 bool FoundSpellCheckingArgument = false;
2758 for (int I = 0; I != num_command_line_args; ++I) {
2759 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2760 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2761 FoundSpellCheckingArgument = true;
2762 break;
2763 }
2764 }
2765 if (!FoundSpellCheckingArgument)
2766 Args->push_back("-fno-spell-checking");
2767
2768 Args->insert(Args->end(), command_line_args,
2769 command_line_args + num_command_line_args);
2770
2771 // The 'source_filename' argument is optional. If the caller does not
2772 // specify it then it is assumed that the source file is specified
2773 // in the actual argument list.
2774 // Put the source file after command_line_args otherwise if '-x' flag is
2775 // present it will be unused.
2776 if (source_filename)
2777 Args->push_back(source_filename);
2778
2779 // Do we need the detailed preprocessing record?
2780 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2781 Args->push_back("-Xclang");
2782 Args->push_back("-detailed-preprocessing-record");
2783 }
2784
2785 unsigned NumErrors = Diags->getClient()->getNumErrors();
2786 OwningPtr<ASTUnit> ErrUnit;
2787 OwningPtr<ASTUnit> Unit(
2788 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2789 /* vector::data() not portable */,
2790 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2791 Diags,
2792 CXXIdx->getClangResourcesPath(),
2793 CXXIdx->getOnlyLocalDecls(),
2794 /*CaptureDiagnostics=*/true,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002795 *RemappedFiles.get(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002796 /*RemappedFilesKeepOriginalName=*/true,
2797 PrecompilePreamble,
2798 TUKind,
Alp Toker8c8a8752013-12-03 06:53:35 +00002799 CacheCodeCompletionResults,
Guy Benyei11169dd2012-12-18 14:30:41 +00002800 IncludeBriefCommentsInCodeCompletion,
2801 /*AllowPCHWithCompilerErrors=*/true,
2802 SkipFunctionBodies,
2803 /*UserFilesAreVolatile=*/true,
2804 ForSerialization,
2805 &ErrUnit));
2806
2807 if (NumErrors != Diags->getClient()->getNumErrors()) {
2808 // Make sure to check that 'Unit' is non-NULL.
2809 if (CXXIdx->getDisplayDiagnostics())
2810 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2811 }
2812
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002813 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2814 PTUI->result = CXError_ASTReadError;
2815 } else {
2816 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.take());
2817 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2818 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002819}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002820
2821CXTranslationUnit
2822clang_parseTranslationUnit(CXIndex CIdx,
2823 const char *source_filename,
2824 const char *const *command_line_args,
2825 int num_command_line_args,
2826 struct CXUnsavedFile *unsaved_files,
2827 unsigned num_unsaved_files,
2828 unsigned options) {
2829 CXTranslationUnit TU;
2830 enum CXErrorCode Result = clang_parseTranslationUnit2(
2831 CIdx, source_filename, command_line_args, num_command_line_args,
2832 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002833 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002834 assert((TU && Result == CXError_Success) ||
2835 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002836 return TU;
2837}
2838
2839enum CXErrorCode clang_parseTranslationUnit2(
2840 CXIndex CIdx,
2841 const char *source_filename,
2842 const char *const *command_line_args,
2843 int num_command_line_args,
2844 struct CXUnsavedFile *unsaved_files,
2845 unsigned num_unsaved_files,
2846 unsigned options,
2847 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002848 LOG_FUNC_SECTION {
2849 *Log << source_filename << ": ";
2850 for (int i = 0; i != num_command_line_args; ++i)
2851 *Log << command_line_args[i] << " ";
2852 }
2853
Guy Benyei11169dd2012-12-18 14:30:41 +00002854 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2855 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002856 num_unsaved_files, options, out_TU,
2857 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002858 llvm::CrashRecoveryContext CRC;
2859
2860 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2861 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2862 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2863 fprintf(stderr, " 'command_line_args' : [");
2864 for (int i = 0; i != num_command_line_args; ++i) {
2865 if (i)
2866 fprintf(stderr, ", ");
2867 fprintf(stderr, "'%s'", command_line_args[i]);
2868 }
2869 fprintf(stderr, "],\n");
2870 fprintf(stderr, " 'unsaved_files' : [");
2871 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2872 if (i)
2873 fprintf(stderr, ", ");
2874 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2875 unsaved_files[i].Length);
2876 }
2877 fprintf(stderr, "],\n");
2878 fprintf(stderr, " 'options' : %d,\n", options);
2879 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002880
2881 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002882 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002883 if (CXTranslationUnit *TU = PTUI.out_TU)
2884 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002885 }
2886
2887 return PTUI.result;
2888}
2889
2890unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2891 return CXSaveTranslationUnit_None;
2892}
2893
2894namespace {
2895
2896struct SaveTranslationUnitInfo {
2897 CXTranslationUnit TU;
2898 const char *FileName;
2899 unsigned options;
2900 CXSaveError result;
2901};
2902
2903}
2904
2905static void clang_saveTranslationUnit_Impl(void *UserData) {
2906 SaveTranslationUnitInfo *STUI =
2907 static_cast<SaveTranslationUnitInfo*>(UserData);
2908
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002909 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002910 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2911 setThreadBackgroundPriority();
2912
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002913 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002914 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2915}
2916
2917int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2918 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002919 LOG_FUNC_SECTION {
2920 *Log << TU << ' ' << FileName;
2921 }
2922
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002923 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002924 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002925 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002926 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002927
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002928 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002929 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2930 if (!CXXUnit->hasSema())
2931 return CXSaveError_InvalidTU;
2932
2933 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2934
2935 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2936 getenv("LIBCLANG_NOTHREADS")) {
2937 clang_saveTranslationUnit_Impl(&STUI);
2938
2939 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2940 PrintLibclangResourceUsage(TU);
2941
2942 return STUI.result;
2943 }
2944
2945 // We have an AST that has invalid nodes due to compiler errors.
2946 // Use a crash recovery thread for protection.
2947
2948 llvm::CrashRecoveryContext CRC;
2949
2950 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2951 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2952 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2953 fprintf(stderr, " 'options' : %d,\n", options);
2954 fprintf(stderr, "}\n");
2955
2956 return CXSaveError_Unknown;
2957
2958 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2959 PrintLibclangResourceUsage(TU);
2960 }
2961
2962 return STUI.result;
2963}
2964
2965void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2966 if (CTUnit) {
2967 // If the translation unit has been marked as unsafe to free, just discard
2968 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002969 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2970 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002971 return;
2972
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002973 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002974 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002975 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2976 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002977 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002978 delete CTUnit;
2979 }
2980}
2981
2982unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2983 return CXReparse_None;
2984}
2985
2986struct ReparseTranslationUnitInfo {
2987 CXTranslationUnit TU;
2988 unsigned num_unsaved_files;
2989 struct CXUnsavedFile *unsaved_files;
2990 unsigned options;
2991 int result;
2992};
2993
2994static void clang_reparseTranslationUnit_Impl(void *UserData) {
2995 ReparseTranslationUnitInfo *RTUI =
2996 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002997 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002998
Guy Benyei11169dd2012-12-18 14:30:41 +00002999 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003000 unsigned num_unsaved_files = RTUI->num_unsaved_files;
3001 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
3002 unsigned options = RTUI->options;
3003 (void) options;
3004
3005 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003006 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003007 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003008 RTUI->result = CXError_InvalidArguments;
3009 return;
3010 }
3011 if (unsaved_files == NULL && num_unsaved_files != 0) {
3012 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003013 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003014 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003015
3016 // Reset the associated diagnostics.
3017 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3018 TU->Diagnostics = 0;
3019
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003020 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003021 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3022 setThreadBackgroundPriority();
3023
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003024 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003025 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3026
3027 OwningPtr<std::vector<ASTUnit::RemappedFile> >
3028 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
3029
3030 // Recover resources if we crash before exiting this function.
3031 llvm::CrashRecoveryContextCleanupRegistrar<
3032 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3033
3034 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3035 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3036 const llvm::MemoryBuffer *Buffer
3037 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3038 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3039 Buffer));
3040 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003041
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003042 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003043 RTUI->result = CXError_Success;
3044 else if (isASTReadError(CXXUnit))
3045 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003046}
3047
3048int clang_reparseTranslationUnit(CXTranslationUnit TU,
3049 unsigned num_unsaved_files,
3050 struct CXUnsavedFile *unsaved_files,
3051 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003052 LOG_FUNC_SECTION {
3053 *Log << TU;
3054 }
3055
Guy Benyei11169dd2012-12-18 14:30:41 +00003056 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003057 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003058
3059 if (getenv("LIBCLANG_NOTHREADS")) {
3060 clang_reparseTranslationUnit_Impl(&RTUI);
3061 return RTUI.result;
3062 }
3063
3064 llvm::CrashRecoveryContext CRC;
3065
3066 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3067 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003068 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003069 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003070 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3071 PrintLibclangResourceUsage(TU);
3072
3073 return RTUI.result;
3074}
3075
3076
3077CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003078 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003079 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003080 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003081 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003082
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003083 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003084 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003085}
3086
3087CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003088 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003089 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003090 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003091 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003092
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003093 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003094 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3095}
3096
3097} // end: extern "C"
3098
3099//===----------------------------------------------------------------------===//
3100// CXFile Operations.
3101//===----------------------------------------------------------------------===//
3102
3103extern "C" {
3104CXString clang_getFileName(CXFile SFile) {
3105 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003106 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003107
3108 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003109 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003110}
3111
3112time_t clang_getFileTime(CXFile SFile) {
3113 if (!SFile)
3114 return 0;
3115
3116 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3117 return FEnt->getModificationTime();
3118}
3119
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003120CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003121 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003122 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003123 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003124 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003125
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003126 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003127
3128 FileManager &FMgr = CXXUnit->getFileManager();
3129 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3130}
3131
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003132unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3133 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003134 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003135 LOG_BAD_TU(TU);
3136 return 0;
3137 }
3138
3139 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003140 return 0;
3141
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003142 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003143 FileEntry *FEnt = static_cast<FileEntry *>(file);
3144 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3145 .isFileMultipleIncludeGuarded(FEnt);
3146}
3147
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003148int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3149 if (!file || !outID)
3150 return 1;
3151
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003152 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003153 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3154 outID->data[0] = ID.getDevice();
3155 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003156 outID->data[2] = FEnt->getModificationTime();
3157 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003158}
3159
Guy Benyei11169dd2012-12-18 14:30:41 +00003160} // end: extern "C"
3161
3162//===----------------------------------------------------------------------===//
3163// CXCursor Operations.
3164//===----------------------------------------------------------------------===//
3165
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003166static const Decl *getDeclFromExpr(const Stmt *E) {
3167 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003168 return getDeclFromExpr(CE->getSubExpr());
3169
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003170 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003171 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003172 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003173 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003174 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003175 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003176 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003177 if (PRE->isExplicitProperty())
3178 return PRE->getExplicitProperty();
3179 // It could be messaging both getter and setter as in:
3180 // ++myobj.myprop;
3181 // in which case prefer to associate the setter since it is less obvious
3182 // from inspecting the source that the setter is going to get called.
3183 if (PRE->isMessagingSetter())
3184 return PRE->getImplicitPropertySetter();
3185 return PRE->getImplicitPropertyGetter();
3186 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003187 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003188 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003189 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003190 if (Expr *Src = OVE->getSourceExpr())
3191 return getDeclFromExpr(Src);
3192
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003193 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003194 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003195 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003196 if (!CE->isElidable())
3197 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003198 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003199 return OME->getMethodDecl();
3200
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003201 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003202 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003203 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003204 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3205 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003206 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003207 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3208 isa<ParmVarDecl>(SizeOfPack->getPack()))
3209 return SizeOfPack->getPack();
3210
3211 return 0;
3212}
3213
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003214static SourceLocation getLocationFromExpr(const Expr *E) {
3215 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003216 return getLocationFromExpr(CE->getSubExpr());
3217
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003218 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003219 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003220 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003221 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003222 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003223 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003224 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003225 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003226 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003227 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003228 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003229 return PropRef->getLocation();
3230
3231 return E->getLocStart();
3232}
3233
3234extern "C" {
3235
3236unsigned clang_visitChildren(CXCursor parent,
3237 CXCursorVisitor visitor,
3238 CXClientData client_data) {
3239 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3240 /*VisitPreprocessorLast=*/false);
3241 return CursorVis.VisitChildren(parent);
3242}
3243
3244#ifndef __has_feature
3245#define __has_feature(x) 0
3246#endif
3247#if __has_feature(blocks)
3248typedef enum CXChildVisitResult
3249 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3250
3251static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3252 CXClientData client_data) {
3253 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3254 return block(cursor, parent);
3255}
3256#else
3257// If we are compiled with a compiler that doesn't have native blocks support,
3258// define and call the block manually, so the
3259typedef struct _CXChildVisitResult
3260{
3261 void *isa;
3262 int flags;
3263 int reserved;
3264 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3265 CXCursor);
3266} *CXCursorVisitorBlock;
3267
3268static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3269 CXClientData client_data) {
3270 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3271 return block->invoke(block, cursor, parent);
3272}
3273#endif
3274
3275
3276unsigned clang_visitChildrenWithBlock(CXCursor parent,
3277 CXCursorVisitorBlock block) {
3278 return clang_visitChildren(parent, visitWithBlock, block);
3279}
3280
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003281static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003282 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003283 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003284
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003285 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003286 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003287 if (const ObjCPropertyImplDecl *PropImpl =
3288 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003289 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003290 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003291
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003292 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003293 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003294 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003295
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003296 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003297 }
3298
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003299 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003300 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003301
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003302 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003303 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3304 // and returns different names. NamedDecl returns the class name and
3305 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003306 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003307
3308 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003309 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003310
3311 SmallString<1024> S;
3312 llvm::raw_svector_ostream os(S);
3313 ND->printName(os);
3314
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003315 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003316}
3317
3318CXString clang_getCursorSpelling(CXCursor C) {
3319 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003320 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003321
3322 if (clang_isReference(C.kind)) {
3323 switch (C.kind) {
3324 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003325 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003326 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003327 }
3328 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003329 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003330 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003331 }
3332 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003333 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003335 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003336 }
3337 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003338 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003339 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003340 }
3341 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003342 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003343 assert(Type && "Missing type decl");
3344
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003345 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003346 getAsString());
3347 }
3348 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003349 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003350 assert(Template && "Missing template decl");
3351
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003352 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003353 }
3354
3355 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003356 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003357 assert(NS && "Missing namespace decl");
3358
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003359 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003360 }
3361
3362 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003363 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003364 assert(Field && "Missing member decl");
3365
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003366 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003367 }
3368
3369 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003370 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003371 assert(Label && "Missing label");
3372
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003373 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003374 }
3375
3376 case CXCursor_OverloadedDeclRef: {
3377 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003378 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3379 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003380 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003381 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003382 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003383 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003384 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003385 OverloadedTemplateStorage *Ovl
3386 = Storage.get<OverloadedTemplateStorage*>();
3387 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003388 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003389 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003390 }
3391
3392 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003393 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003394 assert(Var && "Missing variable decl");
3395
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003396 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003397 }
3398
3399 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003400 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003401 }
3402 }
3403
3404 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003405 const Expr *E = getCursorExpr(C);
3406
3407 if (C.kind == CXCursor_ObjCStringLiteral ||
3408 C.kind == CXCursor_StringLiteral) {
3409 const StringLiteral *SLit;
3410 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3411 SLit = OSL->getString();
3412 } else {
3413 SLit = cast<StringLiteral>(E);
3414 }
3415 SmallString<256> Buf;
3416 llvm::raw_svector_ostream OS(Buf);
3417 SLit->outputString(OS);
3418 return cxstring::createDup(OS.str());
3419 }
3420
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003421 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003422 if (D)
3423 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003424 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003425 }
3426
3427 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003428 const Stmt *S = getCursorStmt(C);
3429 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003430 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003431
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003432 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003433 }
3434
3435 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003436 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003437 ->getNameStart());
3438
3439 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003440 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003441 ->getNameStart());
3442
3443 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003444 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003445
3446 if (clang_isDeclaration(C.kind))
3447 return getDeclSpelling(getCursorDecl(C));
3448
3449 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003450 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003451 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003452 }
3453
3454 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003455 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003456 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003457 }
3458
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003459 if (C.kind == CXCursor_PackedAttr) {
3460 return cxstring::createRef("packed");
3461 }
3462
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003463 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003464}
3465
3466CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3467 unsigned pieceIndex,
3468 unsigned options) {
3469 if (clang_Cursor_isNull(C))
3470 return clang_getNullRange();
3471
3472 ASTContext &Ctx = getCursorContext(C);
3473
3474 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003475 const Stmt *S = getCursorStmt(C);
3476 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003477 if (pieceIndex > 0)
3478 return clang_getNullRange();
3479 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3480 }
3481
3482 return clang_getNullRange();
3483 }
3484
3485 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003486 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003487 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3488 if (pieceIndex >= ME->getNumSelectorLocs())
3489 return clang_getNullRange();
3490 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3491 }
3492 }
3493
3494 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3495 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003496 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003497 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3498 if (pieceIndex >= MD->getNumSelectorLocs())
3499 return clang_getNullRange();
3500 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3501 }
3502 }
3503
3504 if (C.kind == CXCursor_ObjCCategoryDecl ||
3505 C.kind == CXCursor_ObjCCategoryImplDecl) {
3506 if (pieceIndex > 0)
3507 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003508 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003509 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3510 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003511 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003512 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3513 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3514 }
3515
3516 if (C.kind == CXCursor_ModuleImportDecl) {
3517 if (pieceIndex > 0)
3518 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003519 if (const ImportDecl *ImportD =
3520 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003521 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3522 if (!Locs.empty())
3523 return cxloc::translateSourceRange(Ctx,
3524 SourceRange(Locs.front(), Locs.back()));
3525 }
3526 return clang_getNullRange();
3527 }
3528
3529 // FIXME: A CXCursor_InclusionDirective should give the location of the
3530 // filename, but we don't keep track of this.
3531
3532 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3533 // but we don't keep track of this.
3534
3535 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3536 // but we don't keep track of this.
3537
3538 // Default handling, give the location of the cursor.
3539
3540 if (pieceIndex > 0)
3541 return clang_getNullRange();
3542
3543 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3544 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3545 return cxloc::translateSourceRange(Ctx, Loc);
3546}
3547
3548CXString clang_getCursorDisplayName(CXCursor C) {
3549 if (!clang_isDeclaration(C.kind))
3550 return clang_getCursorSpelling(C);
3551
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003552 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003553 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003554 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003555
3556 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003557 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003558 D = FunTmpl->getTemplatedDecl();
3559
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003560 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003561 SmallString<64> Str;
3562 llvm::raw_svector_ostream OS(Str);
3563 OS << *Function;
3564 if (Function->getPrimaryTemplate())
3565 OS << "<>";
3566 OS << "(";
3567 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3568 if (I)
3569 OS << ", ";
3570 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3571 }
3572
3573 if (Function->isVariadic()) {
3574 if (Function->getNumParams())
3575 OS << ", ";
3576 OS << "...";
3577 }
3578 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003579 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003580 }
3581
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003582 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003583 SmallString<64> Str;
3584 llvm::raw_svector_ostream OS(Str);
3585 OS << *ClassTemplate;
3586 OS << "<";
3587 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3588 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3589 if (I)
3590 OS << ", ";
3591
3592 NamedDecl *Param = Params->getParam(I);
3593 if (Param->getIdentifier()) {
3594 OS << Param->getIdentifier()->getName();
3595 continue;
3596 }
3597
3598 // There is no parameter name, which makes this tricky. Try to come up
3599 // with something useful that isn't too long.
3600 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3601 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3602 else if (NonTypeTemplateParmDecl *NTTP
3603 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3604 OS << NTTP->getType().getAsString(Policy);
3605 else
3606 OS << "template<...> class";
3607 }
3608
3609 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003610 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003611 }
3612
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003613 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003614 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3615 // If the type was explicitly written, use that.
3616 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003617 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003618
Benjamin Kramer9170e912013-02-22 15:46:01 +00003619 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003620 llvm::raw_svector_ostream OS(Str);
3621 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003622 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 ClassSpec->getTemplateArgs().data(),
3624 ClassSpec->getTemplateArgs().size(),
3625 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003626 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 }
3628
3629 return clang_getCursorSpelling(C);
3630}
3631
3632CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3633 switch (Kind) {
3634 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003635 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003637 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003641 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003643 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003645 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003647 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003651 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003653 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003655 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003659 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003663 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003665 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003673 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003762 case CXCursor_ObjCSelfExpr:
3763 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003880 case CXCursor_PackedAttr:
3881 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003930 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003931 return cxstring::createRef("OMPParallelDirective");
3932 case CXCursor_OMPSimdDirective:
3933 return cxstring::createRef("OMPSimdDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 }
3935
3936 llvm_unreachable("Unhandled CXCursorKind");
3937}
3938
3939struct GetCursorData {
3940 SourceLocation TokenBeginLoc;
3941 bool PointsAtMacroArgExpansion;
3942 bool VisitedObjCPropertyImplDecl;
3943 SourceLocation VisitedDeclaratorDeclStartLoc;
3944 CXCursor &BestCursor;
3945
3946 GetCursorData(SourceManager &SM,
3947 SourceLocation tokenBegin, CXCursor &outputCursor)
3948 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3949 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3950 VisitedObjCPropertyImplDecl = false;
3951 }
3952};
3953
3954static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3955 CXCursor parent,
3956 CXClientData client_data) {
3957 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3958 CXCursor *BestCursor = &Data->BestCursor;
3959
3960 // If we point inside a macro argument we should provide info of what the
3961 // token is so use the actual cursor, don't replace it with a macro expansion
3962 // cursor.
3963 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3964 return CXChildVisit_Recurse;
3965
3966 if (clang_isDeclaration(cursor.kind)) {
3967 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003968 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003969 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3970 if (MD->isImplicit())
3971 return CXChildVisit_Break;
3972
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003973 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003974 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3975 // Check that when we have multiple @class references in the same line,
3976 // that later ones do not override the previous ones.
3977 // If we have:
3978 // @class Foo, Bar;
3979 // source ranges for both start at '@', so 'Bar' will end up overriding
3980 // 'Foo' even though the cursor location was at 'Foo'.
3981 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3982 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003983 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003984 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3985 if (PrevID != ID &&
3986 !PrevID->isThisDeclarationADefinition() &&
3987 !ID->isThisDeclarationADefinition())
3988 return CXChildVisit_Break;
3989 }
3990
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003991 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3993 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3994 // Check that when we have multiple declarators in the same line,
3995 // that later ones do not override the previous ones.
3996 // If we have:
3997 // int Foo, Bar;
3998 // source ranges for both start at 'int', so 'Bar' will end up overriding
3999 // 'Foo' even though the cursor location was at 'Foo'.
4000 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4001 return CXChildVisit_Break;
4002 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4003
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004004 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4006 (void)PropImp;
4007 // Check that when we have multiple @synthesize in the same line,
4008 // that later ones do not override the previous ones.
4009 // If we have:
4010 // @synthesize Foo, Bar;
4011 // source ranges for both start at '@', so 'Bar' will end up overriding
4012 // 'Foo' even though the cursor location was at 'Foo'.
4013 if (Data->VisitedObjCPropertyImplDecl)
4014 return CXChildVisit_Break;
4015 Data->VisitedObjCPropertyImplDecl = true;
4016 }
4017 }
4018
4019 if (clang_isExpression(cursor.kind) &&
4020 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004021 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004022 // Avoid having the cursor of an expression replace the declaration cursor
4023 // when the expression source range overlaps the declaration range.
4024 // This can happen for C++ constructor expressions whose range generally
4025 // include the variable declaration, e.g.:
4026 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4027 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4028 D->getLocation() == Data->TokenBeginLoc)
4029 return CXChildVisit_Break;
4030 }
4031 }
4032
4033 // If our current best cursor is the construction of a temporary object,
4034 // don't replace that cursor with a type reference, because we want
4035 // clang_getCursor() to point at the constructor.
4036 if (clang_isExpression(BestCursor->kind) &&
4037 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4038 cursor.kind == CXCursor_TypeRef) {
4039 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4040 // as having the actual point on the type reference.
4041 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4042 return CXChildVisit_Recurse;
4043 }
4044
4045 *BestCursor = cursor;
4046 return CXChildVisit_Recurse;
4047}
4048
4049CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004050 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004051 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004053 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004054
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004055 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4057
4058 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4059 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4060
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004061 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004062 CXFile SearchFile;
4063 unsigned SearchLine, SearchColumn;
4064 CXFile ResultFile;
4065 unsigned ResultLine, ResultColumn;
4066 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4067 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4068 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4069
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004070 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4071 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004072 &ResultColumn, 0);
4073 SearchFileName = clang_getFileName(SearchFile);
4074 ResultFileName = clang_getFileName(ResultFile);
4075 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4076 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004077 *Log << llvm::format("(%s:%d:%d) = %s",
4078 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4079 clang_getCString(KindSpelling))
4080 << llvm::format("(%s:%d:%d):%s%s",
4081 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4082 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 clang_disposeString(SearchFileName);
4084 clang_disposeString(ResultFileName);
4085 clang_disposeString(KindSpelling);
4086 clang_disposeString(USR);
4087
4088 CXCursor Definition = clang_getCursorDefinition(Result);
4089 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4090 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4091 CXString DefinitionKindSpelling
4092 = clang_getCursorKindSpelling(Definition.kind);
4093 CXFile DefinitionFile;
4094 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004095 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 &DefinitionLine, &DefinitionColumn, 0);
4097 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004098 *Log << llvm::format(" -> %s(%s:%d:%d)",
4099 clang_getCString(DefinitionKindSpelling),
4100 clang_getCString(DefinitionFileName),
4101 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004102 clang_disposeString(DefinitionFileName);
4103 clang_disposeString(DefinitionKindSpelling);
4104 }
4105 }
4106
4107 return Result;
4108}
4109
4110CXCursor clang_getNullCursor(void) {
4111 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4112}
4113
4114unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004115 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4116 // can't set consistently. For example, when visiting a DeclStmt we will set
4117 // it but we don't set it on the result of clang_getCursorDefinition for
4118 // a reference of the same declaration.
4119 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4120 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4121 // to provide that kind of info.
4122 if (clang_isDeclaration(X.kind))
4123 X.data[1] = 0;
4124 if (clang_isDeclaration(Y.kind))
4125 Y.data[1] = 0;
4126
Guy Benyei11169dd2012-12-18 14:30:41 +00004127 return X == Y;
4128}
4129
4130unsigned clang_hashCursor(CXCursor C) {
4131 unsigned Index = 0;
4132 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4133 Index = 1;
4134
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004135 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004136 std::make_pair(C.kind, C.data[Index]));
4137}
4138
4139unsigned clang_isInvalid(enum CXCursorKind K) {
4140 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4141}
4142
4143unsigned clang_isDeclaration(enum CXCursorKind K) {
4144 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4145 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4146}
4147
4148unsigned clang_isReference(enum CXCursorKind K) {
4149 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4150}
4151
4152unsigned clang_isExpression(enum CXCursorKind K) {
4153 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4154}
4155
4156unsigned clang_isStatement(enum CXCursorKind K) {
4157 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4158}
4159
4160unsigned clang_isAttribute(enum CXCursorKind K) {
4161 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4162}
4163
4164unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4165 return K == CXCursor_TranslationUnit;
4166}
4167
4168unsigned clang_isPreprocessing(enum CXCursorKind K) {
4169 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4170}
4171
4172unsigned clang_isUnexposed(enum CXCursorKind K) {
4173 switch (K) {
4174 case CXCursor_UnexposedDecl:
4175 case CXCursor_UnexposedExpr:
4176 case CXCursor_UnexposedStmt:
4177 case CXCursor_UnexposedAttr:
4178 return true;
4179 default:
4180 return false;
4181 }
4182}
4183
4184CXCursorKind clang_getCursorKind(CXCursor C) {
4185 return C.kind;
4186}
4187
4188CXSourceLocation clang_getCursorLocation(CXCursor C) {
4189 if (clang_isReference(C.kind)) {
4190 switch (C.kind) {
4191 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004192 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 = getCursorObjCSuperClassRef(C);
4194 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4195 }
4196
4197 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004198 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 = getCursorObjCProtocolRef(C);
4200 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4201 }
4202
4203 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004204 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 = getCursorObjCClassRef(C);
4206 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4207 }
4208
4209 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004210 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4212 }
4213
4214 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004215 std::pair<const TemplateDecl *, SourceLocation> P =
4216 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004217 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4218 }
4219
4220 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004221 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004222 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4223 }
4224
4225 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004226 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004227 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4228 }
4229
4230 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004231 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004232 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4233 }
4234
4235 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004236 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004237 if (!BaseSpec)
4238 return clang_getNullLocation();
4239
4240 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4241 return cxloc::translateSourceLocation(getCursorContext(C),
4242 TSInfo->getTypeLoc().getBeginLoc());
4243
4244 return cxloc::translateSourceLocation(getCursorContext(C),
4245 BaseSpec->getLocStart());
4246 }
4247
4248 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004249 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004250 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4251 }
4252
4253 case CXCursor_OverloadedDeclRef:
4254 return cxloc::translateSourceLocation(getCursorContext(C),
4255 getCursorOverloadedDeclRef(C).second);
4256
4257 default:
4258 // FIXME: Need a way to enumerate all non-reference cases.
4259 llvm_unreachable("Missed a reference kind");
4260 }
4261 }
4262
4263 if (clang_isExpression(C.kind))
4264 return cxloc::translateSourceLocation(getCursorContext(C),
4265 getLocationFromExpr(getCursorExpr(C)));
4266
4267 if (clang_isStatement(C.kind))
4268 return cxloc::translateSourceLocation(getCursorContext(C),
4269 getCursorStmt(C)->getLocStart());
4270
4271 if (C.kind == CXCursor_PreprocessingDirective) {
4272 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4273 return cxloc::translateSourceLocation(getCursorContext(C), L);
4274 }
4275
4276 if (C.kind == CXCursor_MacroExpansion) {
4277 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004278 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004279 return cxloc::translateSourceLocation(getCursorContext(C), L);
4280 }
4281
4282 if (C.kind == CXCursor_MacroDefinition) {
4283 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4284 return cxloc::translateSourceLocation(getCursorContext(C), L);
4285 }
4286
4287 if (C.kind == CXCursor_InclusionDirective) {
4288 SourceLocation L
4289 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4290 return cxloc::translateSourceLocation(getCursorContext(C), L);
4291 }
4292
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004293 if (clang_isAttribute(C.kind)) {
4294 SourceLocation L
4295 = cxcursor::getCursorAttr(C)->getLocation();
4296 return cxloc::translateSourceLocation(getCursorContext(C), L);
4297 }
4298
Guy Benyei11169dd2012-12-18 14:30:41 +00004299 if (!clang_isDeclaration(C.kind))
4300 return clang_getNullLocation();
4301
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004302 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004303 if (!D)
4304 return clang_getNullLocation();
4305
4306 SourceLocation Loc = D->getLocation();
4307 // FIXME: Multiple variables declared in a single declaration
4308 // currently lack the information needed to correctly determine their
4309 // ranges when accounting for the type-specifier. We use context
4310 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4311 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004312 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004313 if (!cxcursor::isFirstInDeclGroup(C))
4314 Loc = VD->getLocation();
4315 }
4316
4317 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004318 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004319 Loc = MD->getSelectorStartLoc();
4320
4321 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4322}
4323
4324} // end extern "C"
4325
4326CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4327 assert(TU);
4328
4329 // Guard against an invalid SourceLocation, or we may assert in one
4330 // of the following calls.
4331 if (SLoc.isInvalid())
4332 return clang_getNullCursor();
4333
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004334 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004335
4336 // Translate the given source location to make it point at the beginning of
4337 // the token under the cursor.
4338 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4339 CXXUnit->getASTContext().getLangOpts());
4340
4341 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4342 if (SLoc.isValid()) {
4343 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4344 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4345 /*VisitPreprocessorLast=*/true,
4346 /*VisitIncludedEntities=*/false,
4347 SourceLocation(SLoc));
4348 CursorVis.visitFileRegion();
4349 }
4350
4351 return Result;
4352}
4353
4354static SourceRange getRawCursorExtent(CXCursor C) {
4355 if (clang_isReference(C.kind)) {
4356 switch (C.kind) {
4357 case CXCursor_ObjCSuperClassRef:
4358 return getCursorObjCSuperClassRef(C).second;
4359
4360 case CXCursor_ObjCProtocolRef:
4361 return getCursorObjCProtocolRef(C).second;
4362
4363 case CXCursor_ObjCClassRef:
4364 return getCursorObjCClassRef(C).second;
4365
4366 case CXCursor_TypeRef:
4367 return getCursorTypeRef(C).second;
4368
4369 case CXCursor_TemplateRef:
4370 return getCursorTemplateRef(C).second;
4371
4372 case CXCursor_NamespaceRef:
4373 return getCursorNamespaceRef(C).second;
4374
4375 case CXCursor_MemberRef:
4376 return getCursorMemberRef(C).second;
4377
4378 case CXCursor_CXXBaseSpecifier:
4379 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4380
4381 case CXCursor_LabelRef:
4382 return getCursorLabelRef(C).second;
4383
4384 case CXCursor_OverloadedDeclRef:
4385 return getCursorOverloadedDeclRef(C).second;
4386
4387 case CXCursor_VariableRef:
4388 return getCursorVariableRef(C).second;
4389
4390 default:
4391 // FIXME: Need a way to enumerate all non-reference cases.
4392 llvm_unreachable("Missed a reference kind");
4393 }
4394 }
4395
4396 if (clang_isExpression(C.kind))
4397 return getCursorExpr(C)->getSourceRange();
4398
4399 if (clang_isStatement(C.kind))
4400 return getCursorStmt(C)->getSourceRange();
4401
4402 if (clang_isAttribute(C.kind))
4403 return getCursorAttr(C)->getRange();
4404
4405 if (C.kind == CXCursor_PreprocessingDirective)
4406 return cxcursor::getCursorPreprocessingDirective(C);
4407
4408 if (C.kind == CXCursor_MacroExpansion) {
4409 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004410 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004411 return TU->mapRangeFromPreamble(Range);
4412 }
4413
4414 if (C.kind == CXCursor_MacroDefinition) {
4415 ASTUnit *TU = getCursorASTUnit(C);
4416 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4417 return TU->mapRangeFromPreamble(Range);
4418 }
4419
4420 if (C.kind == CXCursor_InclusionDirective) {
4421 ASTUnit *TU = getCursorASTUnit(C);
4422 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4423 return TU->mapRangeFromPreamble(Range);
4424 }
4425
4426 if (C.kind == CXCursor_TranslationUnit) {
4427 ASTUnit *TU = getCursorASTUnit(C);
4428 FileID MainID = TU->getSourceManager().getMainFileID();
4429 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4430 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4431 return SourceRange(Start, End);
4432 }
4433
4434 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004435 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004436 if (!D)
4437 return SourceRange();
4438
4439 SourceRange R = D->getSourceRange();
4440 // FIXME: Multiple variables declared in a single declaration
4441 // currently lack the information needed to correctly determine their
4442 // ranges when accounting for the type-specifier. We use context
4443 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4444 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004445 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004446 if (!cxcursor::isFirstInDeclGroup(C))
4447 R.setBegin(VD->getLocation());
4448 }
4449 return R;
4450 }
4451 return SourceRange();
4452}
4453
4454/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4455/// the decl-specifier-seq for declarations.
4456static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4457 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004458 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004459 if (!D)
4460 return SourceRange();
4461
4462 SourceRange R = D->getSourceRange();
4463
4464 // Adjust the start of the location for declarations preceded by
4465 // declaration specifiers.
4466 SourceLocation StartLoc;
4467 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4468 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4469 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004470 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004471 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4472 StartLoc = TI->getTypeLoc().getLocStart();
4473 }
4474
4475 if (StartLoc.isValid() && R.getBegin().isValid() &&
4476 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4477 R.setBegin(StartLoc);
4478
4479 // FIXME: Multiple variables declared in a single declaration
4480 // currently lack the information needed to correctly determine their
4481 // ranges when accounting for the type-specifier. We use context
4482 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4483 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004484 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004485 if (!cxcursor::isFirstInDeclGroup(C))
4486 R.setBegin(VD->getLocation());
4487 }
4488
4489 return R;
4490 }
4491
4492 return getRawCursorExtent(C);
4493}
4494
4495extern "C" {
4496
4497CXSourceRange clang_getCursorExtent(CXCursor C) {
4498 SourceRange R = getRawCursorExtent(C);
4499 if (R.isInvalid())
4500 return clang_getNullRange();
4501
4502 return cxloc::translateSourceRange(getCursorContext(C), R);
4503}
4504
4505CXCursor clang_getCursorReferenced(CXCursor C) {
4506 if (clang_isInvalid(C.kind))
4507 return clang_getNullCursor();
4508
4509 CXTranslationUnit tu = getCursorTU(C);
4510 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004511 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004512 if (!D)
4513 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004514 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004515 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004516 if (const ObjCPropertyImplDecl *PropImpl =
4517 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004518 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4519 return MakeCXCursor(Property, tu);
4520
4521 return C;
4522 }
4523
4524 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004525 const Expr *E = getCursorExpr(C);
4526 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004527 if (D) {
4528 CXCursor declCursor = MakeCXCursor(D, tu);
4529 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4530 declCursor);
4531 return declCursor;
4532 }
4533
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004534 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004535 return MakeCursorOverloadedDeclRef(Ovl, tu);
4536
4537 return clang_getNullCursor();
4538 }
4539
4540 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004541 const Stmt *S = getCursorStmt(C);
4542 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004543 if (LabelDecl *label = Goto->getLabel())
4544 if (LabelStmt *labelS = label->getStmt())
4545 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4546
4547 return clang_getNullCursor();
4548 }
4549
4550 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004551 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004552 return MakeMacroDefinitionCursor(Def, tu);
4553 }
4554
4555 if (!clang_isReference(C.kind))
4556 return clang_getNullCursor();
4557
4558 switch (C.kind) {
4559 case CXCursor_ObjCSuperClassRef:
4560 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4561
4562 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004563 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4564 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004565 return MakeCXCursor(Def, tu);
4566
4567 return MakeCXCursor(Prot, tu);
4568 }
4569
4570 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004571 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4572 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004573 return MakeCXCursor(Def, tu);
4574
4575 return MakeCXCursor(Class, tu);
4576 }
4577
4578 case CXCursor_TypeRef:
4579 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4580
4581 case CXCursor_TemplateRef:
4582 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4583
4584 case CXCursor_NamespaceRef:
4585 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4586
4587 case CXCursor_MemberRef:
4588 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4589
4590 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004591 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004592 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4593 tu ));
4594 }
4595
4596 case CXCursor_LabelRef:
4597 // FIXME: We end up faking the "parent" declaration here because we
4598 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004599 return MakeCXCursor(getCursorLabelRef(C).first,
4600 cxtu::getASTUnit(tu)->getASTContext()
4601 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004602 tu);
4603
4604 case CXCursor_OverloadedDeclRef:
4605 return C;
4606
4607 case CXCursor_VariableRef:
4608 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4609
4610 default:
4611 // We would prefer to enumerate all non-reference cursor kinds here.
4612 llvm_unreachable("Unhandled reference cursor kind");
4613 }
4614}
4615
4616CXCursor clang_getCursorDefinition(CXCursor C) {
4617 if (clang_isInvalid(C.kind))
4618 return clang_getNullCursor();
4619
4620 CXTranslationUnit TU = getCursorTU(C);
4621
4622 bool WasReference = false;
4623 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4624 C = clang_getCursorReferenced(C);
4625 WasReference = true;
4626 }
4627
4628 if (C.kind == CXCursor_MacroExpansion)
4629 return clang_getCursorReferenced(C);
4630
4631 if (!clang_isDeclaration(C.kind))
4632 return clang_getNullCursor();
4633
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004634 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004635 if (!D)
4636 return clang_getNullCursor();
4637
4638 switch (D->getKind()) {
4639 // Declaration kinds that don't really separate the notions of
4640 // declaration and definition.
4641 case Decl::Namespace:
4642 case Decl::Typedef:
4643 case Decl::TypeAlias:
4644 case Decl::TypeAliasTemplate:
4645 case Decl::TemplateTypeParm:
4646 case Decl::EnumConstant:
4647 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004648 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004649 case Decl::IndirectField:
4650 case Decl::ObjCIvar:
4651 case Decl::ObjCAtDefsField:
4652 case Decl::ImplicitParam:
4653 case Decl::ParmVar:
4654 case Decl::NonTypeTemplateParm:
4655 case Decl::TemplateTemplateParm:
4656 case Decl::ObjCCategoryImpl:
4657 case Decl::ObjCImplementation:
4658 case Decl::AccessSpec:
4659 case Decl::LinkageSpec:
4660 case Decl::ObjCPropertyImpl:
4661 case Decl::FileScopeAsm:
4662 case Decl::StaticAssert:
4663 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004664 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 case Decl::Label: // FIXME: Is this right??
4666 case Decl::ClassScopeFunctionSpecialization:
4667 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004668 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004669 return C;
4670
4671 // Declaration kinds that don't make any sense here, but are
4672 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004673 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004674 case Decl::TranslationUnit:
4675 break;
4676
4677 // Declaration kinds for which the definition is not resolvable.
4678 case Decl::UnresolvedUsingTypename:
4679 case Decl::UnresolvedUsingValue:
4680 break;
4681
4682 case Decl::UsingDirective:
4683 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4684 TU);
4685
4686 case Decl::NamespaceAlias:
4687 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4688
4689 case Decl::Enum:
4690 case Decl::Record:
4691 case Decl::CXXRecord:
4692 case Decl::ClassTemplateSpecialization:
4693 case Decl::ClassTemplatePartialSpecialization:
4694 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4695 return MakeCXCursor(Def, TU);
4696 return clang_getNullCursor();
4697
4698 case Decl::Function:
4699 case Decl::CXXMethod:
4700 case Decl::CXXConstructor:
4701 case Decl::CXXDestructor:
4702 case Decl::CXXConversion: {
4703 const FunctionDecl *Def = 0;
4704 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004705 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004706 return clang_getNullCursor();
4707 }
4708
Larisse Voufo39a1e502013-08-06 01:03:05 +00004709 case Decl::Var:
4710 case Decl::VarTemplateSpecialization:
4711 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004712 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004713 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004714 return MakeCXCursor(Def, TU);
4715 return clang_getNullCursor();
4716 }
4717
4718 case Decl::FunctionTemplate: {
4719 const FunctionDecl *Def = 0;
4720 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4721 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4722 return clang_getNullCursor();
4723 }
4724
4725 case Decl::ClassTemplate: {
4726 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4727 ->getDefinition())
4728 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4729 TU);
4730 return clang_getNullCursor();
4731 }
4732
Larisse Voufo39a1e502013-08-06 01:03:05 +00004733 case Decl::VarTemplate: {
4734 if (VarDecl *Def =
4735 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4736 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4737 return clang_getNullCursor();
4738 }
4739
Guy Benyei11169dd2012-12-18 14:30:41 +00004740 case Decl::Using:
4741 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4742 D->getLocation(), TU);
4743
4744 case Decl::UsingShadow:
4745 return clang_getCursorDefinition(
4746 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4747 TU));
4748
4749 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004750 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004751 if (Method->isThisDeclarationADefinition())
4752 return C;
4753
4754 // Dig out the method definition in the associated
4755 // @implementation, if we have it.
4756 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004757 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004758 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4759 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4760 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4761 Method->isInstanceMethod()))
4762 if (Def->isThisDeclarationADefinition())
4763 return MakeCXCursor(Def, TU);
4764
4765 return clang_getNullCursor();
4766 }
4767
4768 case Decl::ObjCCategory:
4769 if (ObjCCategoryImplDecl *Impl
4770 = cast<ObjCCategoryDecl>(D)->getImplementation())
4771 return MakeCXCursor(Impl, TU);
4772 return clang_getNullCursor();
4773
4774 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004775 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004776 return MakeCXCursor(Def, TU);
4777 return clang_getNullCursor();
4778
4779 case Decl::ObjCInterface: {
4780 // There are two notions of a "definition" for an Objective-C
4781 // class: the interface and its implementation. When we resolved a
4782 // reference to an Objective-C class, produce the @interface as
4783 // the definition; when we were provided with the interface,
4784 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004785 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004786 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004787 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004788 return MakeCXCursor(Def, TU);
4789 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4790 return MakeCXCursor(Impl, TU);
4791 return clang_getNullCursor();
4792 }
4793
4794 case Decl::ObjCProperty:
4795 // FIXME: We don't really know where to find the
4796 // ObjCPropertyImplDecls that implement this property.
4797 return clang_getNullCursor();
4798
4799 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004800 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004801 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004802 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004803 return MakeCXCursor(Def, TU);
4804
4805 return clang_getNullCursor();
4806
4807 case Decl::Friend:
4808 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4809 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4810 return clang_getNullCursor();
4811
4812 case Decl::FriendTemplate:
4813 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4814 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4815 return clang_getNullCursor();
4816 }
4817
4818 return clang_getNullCursor();
4819}
4820
4821unsigned clang_isCursorDefinition(CXCursor C) {
4822 if (!clang_isDeclaration(C.kind))
4823 return 0;
4824
4825 return clang_getCursorDefinition(C) == C;
4826}
4827
4828CXCursor clang_getCanonicalCursor(CXCursor C) {
4829 if (!clang_isDeclaration(C.kind))
4830 return C;
4831
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004832 if (const Decl *D = getCursorDecl(C)) {
4833 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004834 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4835 return MakeCXCursor(CatD, getCursorTU(C));
4836
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004837 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4838 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004839 return MakeCXCursor(IFD, getCursorTU(C));
4840
4841 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4842 }
4843
4844 return C;
4845}
4846
4847int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4848 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4849}
4850
4851unsigned clang_getNumOverloadedDecls(CXCursor C) {
4852 if (C.kind != CXCursor_OverloadedDeclRef)
4853 return 0;
4854
4855 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004856 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004857 return E->getNumDecls();
4858
4859 if (OverloadedTemplateStorage *S
4860 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4861 return S->size();
4862
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004863 const Decl *D = Storage.get<const Decl *>();
4864 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004865 return Using->shadow_size();
4866
4867 return 0;
4868}
4869
4870CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4871 if (cursor.kind != CXCursor_OverloadedDeclRef)
4872 return clang_getNullCursor();
4873
4874 if (index >= clang_getNumOverloadedDecls(cursor))
4875 return clang_getNullCursor();
4876
4877 CXTranslationUnit TU = getCursorTU(cursor);
4878 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004879 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004880 return MakeCXCursor(E->decls_begin()[index], TU);
4881
4882 if (OverloadedTemplateStorage *S
4883 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4884 return MakeCXCursor(S->begin()[index], TU);
4885
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004886 const Decl *D = Storage.get<const Decl *>();
4887 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004888 // FIXME: This is, unfortunately, linear time.
4889 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4890 std::advance(Pos, index);
4891 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4892 }
4893
4894 return clang_getNullCursor();
4895}
4896
4897void clang_getDefinitionSpellingAndExtent(CXCursor C,
4898 const char **startBuf,
4899 const char **endBuf,
4900 unsigned *startLine,
4901 unsigned *startColumn,
4902 unsigned *endLine,
4903 unsigned *endColumn) {
4904 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004905 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004906 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4907
4908 SourceManager &SM = FD->getASTContext().getSourceManager();
4909 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4910 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4911 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4912 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4913 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4914 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4915}
4916
4917
4918CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4919 unsigned PieceIndex) {
4920 RefNamePieces Pieces;
4921
4922 switch (C.kind) {
4923 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004924 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004925 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4926 E->getQualifierLoc().getSourceRange());
4927 break;
4928
4929 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004930 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004931 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4932 E->getQualifierLoc().getSourceRange(),
4933 E->getOptionalExplicitTemplateArgs());
4934 break;
4935
4936 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004937 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004938 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004939 const Expr *Callee = OCE->getCallee();
4940 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004941 Callee = ICE->getSubExpr();
4942
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004943 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004944 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4945 DRE->getQualifierLoc().getSourceRange());
4946 }
4947 break;
4948
4949 default:
4950 break;
4951 }
4952
4953 if (Pieces.empty()) {
4954 if (PieceIndex == 0)
4955 return clang_getCursorExtent(C);
4956 } else if (PieceIndex < Pieces.size()) {
4957 SourceRange R = Pieces[PieceIndex];
4958 if (R.isValid())
4959 return cxloc::translateSourceRange(getCursorContext(C), R);
4960 }
4961
4962 return clang_getNullRange();
4963}
4964
4965void clang_enableStackTraces(void) {
4966 llvm::sys::PrintStackTraceOnErrorSignal();
4967}
4968
4969void clang_executeOnThread(void (*fn)(void*), void *user_data,
4970 unsigned stack_size) {
4971 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4972}
4973
4974} // end: extern "C"
4975
4976//===----------------------------------------------------------------------===//
4977// Token-based Operations.
4978//===----------------------------------------------------------------------===//
4979
4980/* CXToken layout:
4981 * int_data[0]: a CXTokenKind
4982 * int_data[1]: starting token location
4983 * int_data[2]: token length
4984 * int_data[3]: reserved
4985 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4986 * otherwise unused.
4987 */
4988extern "C" {
4989
4990CXTokenKind clang_getTokenKind(CXToken CXTok) {
4991 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4992}
4993
4994CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4995 switch (clang_getTokenKind(CXTok)) {
4996 case CXToken_Identifier:
4997 case CXToken_Keyword:
4998 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004999 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005000 ->getNameStart());
5001
5002 case CXToken_Literal: {
5003 // We have stashed the starting pointer in the ptr_data field. Use it.
5004 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005005 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005006 }
5007
5008 case CXToken_Punctuation:
5009 case CXToken_Comment:
5010 break;
5011 }
5012
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005013 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005014 LOG_BAD_TU(TU);
5015 return cxstring::createEmpty();
5016 }
5017
Guy Benyei11169dd2012-12-18 14:30:41 +00005018 // We have to find the starting buffer pointer the hard way, by
5019 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005020 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005021 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005022 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005023
5024 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5025 std::pair<FileID, unsigned> LocInfo
5026 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5027 bool Invalid = false;
5028 StringRef Buffer
5029 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5030 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005031 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005032
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005033 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005034}
5035
5036CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005037 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005038 LOG_BAD_TU(TU);
5039 return clang_getNullLocation();
5040 }
5041
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005042 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005043 if (!CXXUnit)
5044 return clang_getNullLocation();
5045
5046 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5047 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5048}
5049
5050CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005051 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005052 LOG_BAD_TU(TU);
5053 return clang_getNullRange();
5054 }
5055
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005056 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005057 if (!CXXUnit)
5058 return clang_getNullRange();
5059
5060 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5061 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5062}
5063
5064static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5065 SmallVectorImpl<CXToken> &CXTokens) {
5066 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5067 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005068 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005069 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005070 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005071
5072 // Cannot tokenize across files.
5073 if (BeginLocInfo.first != EndLocInfo.first)
5074 return;
5075
5076 // Create a lexer
5077 bool Invalid = false;
5078 StringRef Buffer
5079 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5080 if (Invalid)
5081 return;
5082
5083 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5084 CXXUnit->getASTContext().getLangOpts(),
5085 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5086 Lex.SetCommentRetentionState(true);
5087
5088 // Lex tokens until we hit the end of the range.
5089 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5090 Token Tok;
5091 bool previousWasAt = false;
5092 do {
5093 // Lex the next token
5094 Lex.LexFromRawLexer(Tok);
5095 if (Tok.is(tok::eof))
5096 break;
5097
5098 // Initialize the CXToken.
5099 CXToken CXTok;
5100
5101 // - Common fields
5102 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5103 CXTok.int_data[2] = Tok.getLength();
5104 CXTok.int_data[3] = 0;
5105
5106 // - Kind-specific fields
5107 if (Tok.isLiteral()) {
5108 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005109 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005110 } else if (Tok.is(tok::raw_identifier)) {
5111 // Lookup the identifier to determine whether we have a keyword.
5112 IdentifierInfo *II
5113 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5114
5115 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5116 CXTok.int_data[0] = CXToken_Keyword;
5117 }
5118 else {
5119 CXTok.int_data[0] = Tok.is(tok::identifier)
5120 ? CXToken_Identifier
5121 : CXToken_Keyword;
5122 }
5123 CXTok.ptr_data = II;
5124 } else if (Tok.is(tok::comment)) {
5125 CXTok.int_data[0] = CXToken_Comment;
5126 CXTok.ptr_data = 0;
5127 } else {
5128 CXTok.int_data[0] = CXToken_Punctuation;
5129 CXTok.ptr_data = 0;
5130 }
5131 CXTokens.push_back(CXTok);
5132 previousWasAt = Tok.is(tok::at);
5133 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5134}
5135
5136void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5137 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005138 LOG_FUNC_SECTION {
5139 *Log << TU << ' ' << Range;
5140 }
5141
Guy Benyei11169dd2012-12-18 14:30:41 +00005142 if (Tokens)
5143 *Tokens = 0;
5144 if (NumTokens)
5145 *NumTokens = 0;
5146
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005147 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005148 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005149 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005150 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005151
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005152 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005153 if (!CXXUnit || !Tokens || !NumTokens)
5154 return;
5155
5156 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5157
5158 SourceRange R = cxloc::translateCXSourceRange(Range);
5159 if (R.isInvalid())
5160 return;
5161
5162 SmallVector<CXToken, 32> CXTokens;
5163 getTokens(CXXUnit, R, CXTokens);
5164
5165 if (CXTokens.empty())
5166 return;
5167
5168 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5169 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5170 *NumTokens = CXTokens.size();
5171}
5172
5173void clang_disposeTokens(CXTranslationUnit TU,
5174 CXToken *Tokens, unsigned NumTokens) {
5175 free(Tokens);
5176}
5177
5178} // end: extern "C"
5179
5180//===----------------------------------------------------------------------===//
5181// Token annotation APIs.
5182//===----------------------------------------------------------------------===//
5183
Guy Benyei11169dd2012-12-18 14:30:41 +00005184static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5185 CXCursor parent,
5186 CXClientData client_data);
5187static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5188 CXClientData client_data);
5189
5190namespace {
5191class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005192 CXToken *Tokens;
5193 CXCursor *Cursors;
5194 unsigned NumTokens;
5195 unsigned TokIdx;
5196 unsigned PreprocessingTokIdx;
5197 CursorVisitor AnnotateVis;
5198 SourceManager &SrcMgr;
5199 bool HasContextSensitiveKeywords;
5200
5201 struct PostChildrenInfo {
5202 CXCursor Cursor;
5203 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005204 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005205 unsigned BeforeChildrenTokenIdx;
5206 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005207 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005208
5209 CXToken &getTok(unsigned Idx) {
5210 assert(Idx < NumTokens);
5211 return Tokens[Idx];
5212 }
5213 const CXToken &getTok(unsigned Idx) const {
5214 assert(Idx < NumTokens);
5215 return Tokens[Idx];
5216 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005217 bool MoreTokens() const { return TokIdx < NumTokens; }
5218 unsigned NextToken() const { return TokIdx; }
5219 void AdvanceToken() { ++TokIdx; }
5220 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005221 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005222 }
5223 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005224 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005225 }
5226 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005227 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 }
5229
5230 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005231 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005232 SourceRange);
5233
5234public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005235 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005236 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005237 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005238 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005239 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005240 AnnotateTokensVisitor, this,
5241 /*VisitPreprocessorLast=*/true,
5242 /*VisitIncludedEntities=*/false,
5243 RegionOfInterest,
5244 /*VisitDeclsOnly=*/false,
5245 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005246 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005247 HasContextSensitiveKeywords(false) { }
5248
5249 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5250 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5251 bool postVisitChildren(CXCursor cursor);
5252 void AnnotateTokens();
5253
5254 /// \brief Determine whether the annotator saw any cursors that have
5255 /// context-sensitive keywords.
5256 bool hasContextSensitiveKeywords() const {
5257 return HasContextSensitiveKeywords;
5258 }
5259
5260 ~AnnotateTokensWorker() {
5261 assert(PostChildrenInfos.empty());
5262 }
5263};
5264}
5265
5266void AnnotateTokensWorker::AnnotateTokens() {
5267 // Walk the AST within the region of interest, annotating tokens
5268 // along the way.
5269 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005270}
Guy Benyei11169dd2012-12-18 14:30:41 +00005271
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005272static inline void updateCursorAnnotation(CXCursor &Cursor,
5273 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005274 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005275 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005276 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005277}
5278
5279/// \brief It annotates and advances tokens with a cursor until the comparison
5280//// between the cursor location and the source range is the same as
5281/// \arg compResult.
5282///
5283/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5284/// Pass RangeOverlap to annotate tokens inside a range.
5285void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5286 RangeComparisonResult compResult,
5287 SourceRange range) {
5288 while (MoreTokens()) {
5289 const unsigned I = NextToken();
5290 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005291 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5292 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005293
5294 SourceLocation TokLoc = GetTokenLoc(I);
5295 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005296 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005297 AdvanceToken();
5298 continue;
5299 }
5300 break;
5301 }
5302}
5303
5304/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005305/// \returns true if it advanced beyond all macro tokens, false otherwise.
5306bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005307 CXCursor updateC,
5308 RangeComparisonResult compResult,
5309 SourceRange range) {
5310 assert(MoreTokens());
5311 assert(isFunctionMacroToken(NextToken()) &&
5312 "Should be called only for macro arg tokens");
5313
5314 // This works differently than annotateAndAdvanceTokens; because expanded
5315 // macro arguments can have arbitrary translation-unit source order, we do not
5316 // advance the token index one by one until a token fails the range test.
5317 // We only advance once past all of the macro arg tokens if all of them
5318 // pass the range test. If one of them fails we keep the token index pointing
5319 // at the start of the macro arg tokens so that the failing token will be
5320 // annotated by a subsequent annotation try.
5321
5322 bool atLeastOneCompFail = false;
5323
5324 unsigned I = NextToken();
5325 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5326 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5327 if (TokLoc.isFileID())
5328 continue; // not macro arg token, it's parens or comma.
5329 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5330 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5331 Cursors[I] = updateC;
5332 } else
5333 atLeastOneCompFail = true;
5334 }
5335
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005336 if (atLeastOneCompFail)
5337 return false;
5338
5339 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5340 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005341}
5342
5343enum CXChildVisitResult
5344AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005345 SourceRange cursorRange = getRawCursorExtent(cursor);
5346 if (cursorRange.isInvalid())
5347 return CXChildVisit_Recurse;
5348
5349 if (!HasContextSensitiveKeywords) {
5350 // Objective-C properties can have context-sensitive keywords.
5351 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005352 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005353 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5354 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5355 }
5356 // Objective-C methods can have context-sensitive keywords.
5357 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5358 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005359 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005360 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5361 if (Method->getObjCDeclQualifier())
5362 HasContextSensitiveKeywords = true;
5363 else {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005364 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5365 PEnd = Method->param_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00005366 P != PEnd; ++P) {
5367 if ((*P)->getObjCDeclQualifier()) {
5368 HasContextSensitiveKeywords = true;
5369 break;
5370 }
5371 }
5372 }
5373 }
5374 }
5375 // C++ methods can have context-sensitive keywords.
5376 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005377 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005378 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5379 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5380 HasContextSensitiveKeywords = true;
5381 }
5382 }
5383 // C++ classes can have context-sensitive keywords.
5384 else if (cursor.kind == CXCursor_StructDecl ||
5385 cursor.kind == CXCursor_ClassDecl ||
5386 cursor.kind == CXCursor_ClassTemplate ||
5387 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005388 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005389 if (D->hasAttr<FinalAttr>())
5390 HasContextSensitiveKeywords = true;
5391 }
5392 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005393
5394 // Don't override a property annotation with its getter/setter method.
5395 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5396 parent.kind == CXCursor_ObjCPropertyDecl)
5397 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005398
5399 if (clang_isPreprocessing(cursor.kind)) {
5400 // Items in the preprocessing record are kept separate from items in
5401 // declarations, so we keep a separate token index.
5402 unsigned SavedTokIdx = TokIdx;
5403 TokIdx = PreprocessingTokIdx;
5404
5405 // Skip tokens up until we catch up to the beginning of the preprocessing
5406 // entry.
5407 while (MoreTokens()) {
5408 const unsigned I = NextToken();
5409 SourceLocation TokLoc = GetTokenLoc(I);
5410 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5411 case RangeBefore:
5412 AdvanceToken();
5413 continue;
5414 case RangeAfter:
5415 case RangeOverlap:
5416 break;
5417 }
5418 break;
5419 }
5420
5421 // Look at all of the tokens within this range.
5422 while (MoreTokens()) {
5423 const unsigned I = NextToken();
5424 SourceLocation TokLoc = GetTokenLoc(I);
5425 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5426 case RangeBefore:
5427 llvm_unreachable("Infeasible");
5428 case RangeAfter:
5429 break;
5430 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005431 // For macro expansions, just note where the beginning of the macro
5432 // expansion occurs.
5433 if (cursor.kind == CXCursor_MacroExpansion) {
5434 if (TokLoc == cursorRange.getBegin())
5435 Cursors[I] = cursor;
5436 AdvanceToken();
5437 break;
5438 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005439 // We may have already annotated macro names inside macro definitions.
5440 if (Cursors[I].kind != CXCursor_MacroExpansion)
5441 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005442 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005443 continue;
5444 }
5445 break;
5446 }
5447
5448 // Save the preprocessing token index; restore the non-preprocessing
5449 // token index.
5450 PreprocessingTokIdx = TokIdx;
5451 TokIdx = SavedTokIdx;
5452 return CXChildVisit_Recurse;
5453 }
5454
5455 if (cursorRange.isInvalid())
5456 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005457
5458 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005459 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005460 const enum CXCursorKind K = clang_getCursorKind(parent);
5461 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005462 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5463 // Attributes are annotated out-of-order, skip tokens until we reach it.
5464 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005465 ? clang_getNullCursor() : parent;
5466
5467 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5468
5469 // Avoid having the cursor of an expression "overwrite" the annotation of the
5470 // variable declaration that it belongs to.
5471 // This can happen for C++ constructor expressions whose range generally
5472 // include the variable declaration, e.g.:
5473 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005474 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005475 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005476 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005477 const unsigned I = NextToken();
5478 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5479 E->getLocStart() == D->getLocation() &&
5480 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005481 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005482 AdvanceToken();
5483 }
5484 }
5485 }
5486
5487 // Before recursing into the children keep some state that we are going
5488 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5489 // extra work after the child nodes are visited.
5490 // Note that we don't call VisitChildren here to avoid traversing statements
5491 // code-recursively which can blow the stack.
5492
5493 PostChildrenInfo Info;
5494 Info.Cursor = cursor;
5495 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005496 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005497 Info.BeforeChildrenTokenIdx = NextToken();
5498 PostChildrenInfos.push_back(Info);
5499
5500 return CXChildVisit_Recurse;
5501}
5502
5503bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5504 if (PostChildrenInfos.empty())
5505 return false;
5506 const PostChildrenInfo &Info = PostChildrenInfos.back();
5507 if (!clang_equalCursors(Info.Cursor, cursor))
5508 return false;
5509
5510 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5511 const unsigned AfterChildren = NextToken();
5512 SourceRange cursorRange = Info.CursorRange;
5513
5514 // Scan the tokens that are at the end of the cursor, but are not captured
5515 // but the child cursors.
5516 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5517
5518 // Scan the tokens that are at the beginning of the cursor, but are not
5519 // capture by the child cursors.
5520 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5521 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5522 break;
5523
5524 Cursors[I] = cursor;
5525 }
5526
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005527 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5528 // encountered the attribute cursor.
5529 if (clang_isAttribute(cursor.kind))
5530 TokIdx = Info.BeforeReachingCursorIdx;
5531
Guy Benyei11169dd2012-12-18 14:30:41 +00005532 PostChildrenInfos.pop_back();
5533 return false;
5534}
5535
5536static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5537 CXCursor parent,
5538 CXClientData client_data) {
5539 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5540}
5541
5542static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5543 CXClientData client_data) {
5544 return static_cast<AnnotateTokensWorker*>(client_data)->
5545 postVisitChildren(cursor);
5546}
5547
5548namespace {
5549
5550/// \brief Uses the macro expansions in the preprocessing record to find
5551/// and mark tokens that are macro arguments. This info is used by the
5552/// AnnotateTokensWorker.
5553class MarkMacroArgTokensVisitor {
5554 SourceManager &SM;
5555 CXToken *Tokens;
5556 unsigned NumTokens;
5557 unsigned CurIdx;
5558
5559public:
5560 MarkMacroArgTokensVisitor(SourceManager &SM,
5561 CXToken *tokens, unsigned numTokens)
5562 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5563
5564 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5565 if (cursor.kind != CXCursor_MacroExpansion)
5566 return CXChildVisit_Continue;
5567
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005568 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005569 if (macroRange.getBegin() == macroRange.getEnd())
5570 return CXChildVisit_Continue; // it's not a function macro.
5571
5572 for (; CurIdx < NumTokens; ++CurIdx) {
5573 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5574 macroRange.getBegin()))
5575 break;
5576 }
5577
5578 if (CurIdx == NumTokens)
5579 return CXChildVisit_Break;
5580
5581 for (; CurIdx < NumTokens; ++CurIdx) {
5582 SourceLocation tokLoc = getTokenLoc(CurIdx);
5583 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5584 break;
5585
5586 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5587 }
5588
5589 if (CurIdx == NumTokens)
5590 return CXChildVisit_Break;
5591
5592 return CXChildVisit_Continue;
5593 }
5594
5595private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005596 CXToken &getTok(unsigned Idx) {
5597 assert(Idx < NumTokens);
5598 return Tokens[Idx];
5599 }
5600 const CXToken &getTok(unsigned Idx) const {
5601 assert(Idx < NumTokens);
5602 return Tokens[Idx];
5603 }
5604
Guy Benyei11169dd2012-12-18 14:30:41 +00005605 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005606 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005607 }
5608
5609 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5610 // The third field is reserved and currently not used. Use it here
5611 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005612 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005613 }
5614};
5615
5616} // end anonymous namespace
5617
5618static CXChildVisitResult
5619MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5620 CXClientData client_data) {
5621 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5622 parent);
5623}
5624
5625namespace {
5626 struct clang_annotateTokens_Data {
5627 CXTranslationUnit TU;
5628 ASTUnit *CXXUnit;
5629 CXToken *Tokens;
5630 unsigned NumTokens;
5631 CXCursor *Cursors;
5632 };
5633}
5634
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005635/// \brief Used by \c annotatePreprocessorTokens.
5636/// \returns true if lexing was finished, false otherwise.
5637static bool lexNext(Lexer &Lex, Token &Tok,
5638 unsigned &NextIdx, unsigned NumTokens) {
5639 if (NextIdx >= NumTokens)
5640 return true;
5641
5642 ++NextIdx;
5643 Lex.LexFromRawLexer(Tok);
5644 if (Tok.is(tok::eof))
5645 return true;
5646
5647 return false;
5648}
5649
Guy Benyei11169dd2012-12-18 14:30:41 +00005650static void annotatePreprocessorTokens(CXTranslationUnit TU,
5651 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005652 CXCursor *Cursors,
5653 CXToken *Tokens,
5654 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005655 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005656
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005657 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005658 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5659 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005660 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005661 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005662 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005663
5664 if (BeginLocInfo.first != EndLocInfo.first)
5665 return;
5666
5667 StringRef Buffer;
5668 bool Invalid = false;
5669 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5670 if (Buffer.empty() || Invalid)
5671 return;
5672
5673 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5674 CXXUnit->getASTContext().getLangOpts(),
5675 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5676 Buffer.end());
5677 Lex.SetCommentRetentionState(true);
5678
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005679 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005680 // Lex tokens in raw mode until we hit the end of the range, to avoid
5681 // entering #includes or expanding macros.
5682 while (true) {
5683 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005684 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5685 break;
5686 unsigned TokIdx = NextIdx-1;
5687 assert(Tok.getLocation() ==
5688 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005689
5690 reprocess:
5691 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005692 // We have found a preprocessing directive. Annotate the tokens
5693 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005694 //
5695 // FIXME: Some simple tests here could identify macro definitions and
5696 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005697
5698 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005699 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5700 break;
5701
5702 MacroInfo *MI = 0;
5703 if (Tok.is(tok::raw_identifier) &&
5704 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5705 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5706 break;
5707
5708 if (Tok.is(tok::raw_identifier)) {
5709 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5710 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5711 SourceLocation MappedTokLoc =
5712 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5713 MI = getMacroInfo(II, MappedTokLoc, TU);
5714 }
5715 }
5716
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005717 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005718 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005719 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5720 finished = true;
5721 break;
5722 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005723 // If we are in a macro definition, check if the token was ever a
5724 // macro name and annotate it if that's the case.
5725 if (MI) {
5726 SourceLocation SaveLoc = Tok.getLocation();
5727 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5728 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5729 Tok.setLocation(SaveLoc);
5730 if (MacroDef)
5731 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5732 Tok.getLocation(), TU);
5733 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005734 } while (!Tok.isAtStartOfLine());
5735
5736 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5737 assert(TokIdx <= LastIdx);
5738 SourceLocation EndLoc =
5739 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5740 CXCursor Cursor =
5741 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5742
5743 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005744 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005745
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005746 if (finished)
5747 break;
5748 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005749 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005750 }
5751}
5752
5753// This gets run a separate thread to avoid stack blowout.
5754static void clang_annotateTokensImpl(void *UserData) {
5755 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5756 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5757 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5758 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5759 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5760
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005761 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005762 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5763 setThreadBackgroundPriority();
5764
5765 // Determine the region of interest, which contains all of the tokens.
5766 SourceRange RegionOfInterest;
5767 RegionOfInterest.setBegin(
5768 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5769 RegionOfInterest.setEnd(
5770 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5771 Tokens[NumTokens-1])));
5772
Guy Benyei11169dd2012-12-18 14:30:41 +00005773 // Relex the tokens within the source range to look for preprocessing
5774 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005775 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005776
5777 // If begin location points inside a macro argument, set it to the expansion
5778 // location so we can have the full context when annotating semantically.
5779 {
5780 SourceManager &SM = CXXUnit->getSourceManager();
5781 SourceLocation Loc =
5782 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5783 if (Loc.isMacroID())
5784 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5785 }
5786
Guy Benyei11169dd2012-12-18 14:30:41 +00005787 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5788 // Search and mark tokens that are macro argument expansions.
5789 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5790 Tokens, NumTokens);
5791 CursorVisitor MacroArgMarker(TU,
5792 MarkMacroArgTokensVisitorDelegate, &Visitor,
5793 /*VisitPreprocessorLast=*/true,
5794 /*VisitIncludedEntities=*/false,
5795 RegionOfInterest);
5796 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5797 }
5798
5799 // Annotate all of the source locations in the region of interest that map to
5800 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005801 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005802
5803 // FIXME: We use a ridiculous stack size here because the data-recursion
5804 // algorithm uses a large stack frame than the non-data recursive version,
5805 // and AnnotationTokensWorker currently transforms the data-recursion
5806 // algorithm back into a traditional recursion by explicitly calling
5807 // VisitChildren(). We will need to remove this explicit recursive call.
5808 W.AnnotateTokens();
5809
5810 // If we ran into any entities that involve context-sensitive keywords,
5811 // take another pass through the tokens to mark them as such.
5812 if (W.hasContextSensitiveKeywords()) {
5813 for (unsigned I = 0; I != NumTokens; ++I) {
5814 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5815 continue;
5816
5817 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5818 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005819 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005820 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5821 if (Property->getPropertyAttributesAsWritten() != 0 &&
5822 llvm::StringSwitch<bool>(II->getName())
5823 .Case("readonly", true)
5824 .Case("assign", true)
5825 .Case("unsafe_unretained", true)
5826 .Case("readwrite", true)
5827 .Case("retain", true)
5828 .Case("copy", true)
5829 .Case("nonatomic", true)
5830 .Case("atomic", true)
5831 .Case("getter", true)
5832 .Case("setter", true)
5833 .Case("strong", true)
5834 .Case("weak", true)
5835 .Default(false))
5836 Tokens[I].int_data[0] = CXToken_Keyword;
5837 }
5838 continue;
5839 }
5840
5841 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5842 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5843 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5844 if (llvm::StringSwitch<bool>(II->getName())
5845 .Case("in", true)
5846 .Case("out", true)
5847 .Case("inout", true)
5848 .Case("oneway", true)
5849 .Case("bycopy", true)
5850 .Case("byref", true)
5851 .Default(false))
5852 Tokens[I].int_data[0] = CXToken_Keyword;
5853 continue;
5854 }
5855
5856 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5857 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5858 Tokens[I].int_data[0] = CXToken_Keyword;
5859 continue;
5860 }
5861 }
5862 }
5863}
5864
5865extern "C" {
5866
5867void clang_annotateTokens(CXTranslationUnit TU,
5868 CXToken *Tokens, unsigned NumTokens,
5869 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005870 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005871 LOG_BAD_TU(TU);
5872 return;
5873 }
5874 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005875 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005876 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005877 }
5878
5879 LOG_FUNC_SECTION {
5880 *Log << TU << ' ';
5881 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5882 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5883 *Log << clang_getRange(bloc, eloc);
5884 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005885
5886 // Any token we don't specifically annotate will have a NULL cursor.
5887 CXCursor C = clang_getNullCursor();
5888 for (unsigned I = 0; I != NumTokens; ++I)
5889 Cursors[I] = C;
5890
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005891 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005892 if (!CXXUnit)
5893 return;
5894
5895 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5896
5897 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5898 llvm::CrashRecoveryContext CRC;
5899 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5900 GetSafetyThreadStackSize() * 2)) {
5901 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5902 }
5903}
5904
5905} // end: extern "C"
5906
5907//===----------------------------------------------------------------------===//
5908// Operations for querying linkage of a cursor.
5909//===----------------------------------------------------------------------===//
5910
5911extern "C" {
5912CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5913 if (!clang_isDeclaration(cursor.kind))
5914 return CXLinkage_Invalid;
5915
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005916 const Decl *D = cxcursor::getCursorDecl(cursor);
5917 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005918 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005919 case NoLinkage:
5920 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005921 case InternalLinkage: return CXLinkage_Internal;
5922 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5923 case ExternalLinkage: return CXLinkage_External;
5924 };
5925
5926 return CXLinkage_Invalid;
5927}
5928} // end: extern "C"
5929
5930//===----------------------------------------------------------------------===//
5931// Operations for querying language of a cursor.
5932//===----------------------------------------------------------------------===//
5933
5934static CXLanguageKind getDeclLanguage(const Decl *D) {
5935 if (!D)
5936 return CXLanguage_C;
5937
5938 switch (D->getKind()) {
5939 default:
5940 break;
5941 case Decl::ImplicitParam:
5942 case Decl::ObjCAtDefsField:
5943 case Decl::ObjCCategory:
5944 case Decl::ObjCCategoryImpl:
5945 case Decl::ObjCCompatibleAlias:
5946 case Decl::ObjCImplementation:
5947 case Decl::ObjCInterface:
5948 case Decl::ObjCIvar:
5949 case Decl::ObjCMethod:
5950 case Decl::ObjCProperty:
5951 case Decl::ObjCPropertyImpl:
5952 case Decl::ObjCProtocol:
5953 return CXLanguage_ObjC;
5954 case Decl::CXXConstructor:
5955 case Decl::CXXConversion:
5956 case Decl::CXXDestructor:
5957 case Decl::CXXMethod:
5958 case Decl::CXXRecord:
5959 case Decl::ClassTemplate:
5960 case Decl::ClassTemplatePartialSpecialization:
5961 case Decl::ClassTemplateSpecialization:
5962 case Decl::Friend:
5963 case Decl::FriendTemplate:
5964 case Decl::FunctionTemplate:
5965 case Decl::LinkageSpec:
5966 case Decl::Namespace:
5967 case Decl::NamespaceAlias:
5968 case Decl::NonTypeTemplateParm:
5969 case Decl::StaticAssert:
5970 case Decl::TemplateTemplateParm:
5971 case Decl::TemplateTypeParm:
5972 case Decl::UnresolvedUsingTypename:
5973 case Decl::UnresolvedUsingValue:
5974 case Decl::Using:
5975 case Decl::UsingDirective:
5976 case Decl::UsingShadow:
5977 return CXLanguage_CPlusPlus;
5978 }
5979
5980 return CXLanguage_C;
5981}
5982
5983extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005984
5985static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5986 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5987 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005988
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005989 switch (D->getAvailability()) {
5990 case AR_Available:
5991 case AR_NotYetIntroduced:
5992 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005993 return getCursorAvailabilityForDecl(
5994 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005995 return CXAvailability_Available;
5996
5997 case AR_Deprecated:
5998 return CXAvailability_Deprecated;
5999
6000 case AR_Unavailable:
6001 return CXAvailability_NotAvailable;
6002 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006003
6004 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006005}
6006
Guy Benyei11169dd2012-12-18 14:30:41 +00006007enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6008 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006009 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6010 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006011
6012 return CXAvailability_Available;
6013}
6014
6015static CXVersion convertVersion(VersionTuple In) {
6016 CXVersion Out = { -1, -1, -1 };
6017 if (In.empty())
6018 return Out;
6019
6020 Out.Major = In.getMajor();
6021
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006022 Optional<unsigned> Minor = In.getMinor();
6023 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006024 Out.Minor = *Minor;
6025 else
6026 return Out;
6027
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006028 Optional<unsigned> Subminor = In.getSubminor();
6029 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006030 Out.Subminor = *Subminor;
6031
6032 return Out;
6033}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006034
6035static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6036 int *always_deprecated,
6037 CXString *deprecated_message,
6038 int *always_unavailable,
6039 CXString *unavailable_message,
6040 CXPlatformAvailability *availability,
6041 int availability_size) {
6042 bool HadAvailAttr = false;
6043 int N = 0;
6044 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
6045 ++A) {
6046 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
6047 HadAvailAttr = true;
6048 if (always_deprecated)
6049 *always_deprecated = 1;
6050 if (deprecated_message)
6051 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
6052 continue;
6053 }
6054
6055 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
6056 HadAvailAttr = true;
6057 if (always_unavailable)
6058 *always_unavailable = 1;
6059 if (unavailable_message) {
6060 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6061 }
6062 continue;
6063 }
6064
6065 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
6066 HadAvailAttr = true;
6067 if (N < availability_size) {
6068 availability[N].Platform
6069 = cxstring::createDup(Avail->getPlatform()->getName());
6070 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6071 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6072 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6073 availability[N].Unavailable = Avail->getUnavailable();
6074 availability[N].Message = cxstring::createDup(Avail->getMessage());
6075 }
6076 ++N;
6077 }
6078 }
6079
6080 if (!HadAvailAttr)
6081 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6082 return getCursorPlatformAvailabilityForDecl(
6083 cast<Decl>(EnumConst->getDeclContext()),
6084 always_deprecated,
6085 deprecated_message,
6086 always_unavailable,
6087 unavailable_message,
6088 availability,
6089 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006090
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006091 return N;
6092}
6093
Guy Benyei11169dd2012-12-18 14:30:41 +00006094int clang_getCursorPlatformAvailability(CXCursor cursor,
6095 int *always_deprecated,
6096 CXString *deprecated_message,
6097 int *always_unavailable,
6098 CXString *unavailable_message,
6099 CXPlatformAvailability *availability,
6100 int availability_size) {
6101 if (always_deprecated)
6102 *always_deprecated = 0;
6103 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006104 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006105 if (always_unavailable)
6106 *always_unavailable = 0;
6107 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006108 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006109
Guy Benyei11169dd2012-12-18 14:30:41 +00006110 if (!clang_isDeclaration(cursor.kind))
6111 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006112
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006113 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006114 if (!D)
6115 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006116
6117 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6118 deprecated_message,
6119 always_unavailable,
6120 unavailable_message,
6121 availability,
6122 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006123}
6124
6125void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6126 clang_disposeString(availability->Platform);
6127 clang_disposeString(availability->Message);
6128}
6129
6130CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6131 if (clang_isDeclaration(cursor.kind))
6132 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6133
6134 return CXLanguage_Invalid;
6135}
6136
6137 /// \brief If the given cursor is the "templated" declaration
6138 /// descibing a class or function template, return the class or
6139 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006140static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006141 if (!D)
6142 return 0;
6143
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006144 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006145 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6146 return FunTmpl;
6147
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006148 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006149 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6150 return ClassTmpl;
6151
6152 return D;
6153}
6154
6155CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6156 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006157 if (const Decl *D = getCursorDecl(cursor)) {
6158 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006159 if (!DC)
6160 return clang_getNullCursor();
6161
6162 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6163 getCursorTU(cursor));
6164 }
6165 }
6166
6167 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006168 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006169 return MakeCXCursor(D, getCursorTU(cursor));
6170 }
6171
6172 return clang_getNullCursor();
6173}
6174
6175CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6176 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006177 if (const Decl *D = getCursorDecl(cursor)) {
6178 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006179 if (!DC)
6180 return clang_getNullCursor();
6181
6182 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6183 getCursorTU(cursor));
6184 }
6185 }
6186
6187 // FIXME: Note that we can't easily compute the lexical context of a
6188 // statement or expression, so we return nothing.
6189 return clang_getNullCursor();
6190}
6191
6192CXFile clang_getIncludedFile(CXCursor cursor) {
6193 if (cursor.kind != CXCursor_InclusionDirective)
6194 return 0;
6195
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006196 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006197 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006198}
6199
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006200unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6201 if (C.kind != CXCursor_ObjCPropertyDecl)
6202 return CXObjCPropertyAttr_noattr;
6203
6204 unsigned Result = CXObjCPropertyAttr_noattr;
6205 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6206 ObjCPropertyDecl::PropertyAttributeKind Attr =
6207 PD->getPropertyAttributesAsWritten();
6208
6209#define SET_CXOBJCPROP_ATTR(A) \
6210 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6211 Result |= CXObjCPropertyAttr_##A
6212 SET_CXOBJCPROP_ATTR(readonly);
6213 SET_CXOBJCPROP_ATTR(getter);
6214 SET_CXOBJCPROP_ATTR(assign);
6215 SET_CXOBJCPROP_ATTR(readwrite);
6216 SET_CXOBJCPROP_ATTR(retain);
6217 SET_CXOBJCPROP_ATTR(copy);
6218 SET_CXOBJCPROP_ATTR(nonatomic);
6219 SET_CXOBJCPROP_ATTR(setter);
6220 SET_CXOBJCPROP_ATTR(atomic);
6221 SET_CXOBJCPROP_ATTR(weak);
6222 SET_CXOBJCPROP_ATTR(strong);
6223 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6224#undef SET_CXOBJCPROP_ATTR
6225
6226 return Result;
6227}
6228
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006229unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6230 if (!clang_isDeclaration(C.kind))
6231 return CXObjCDeclQualifier_None;
6232
6233 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6234 const Decl *D = getCursorDecl(C);
6235 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6236 QT = MD->getObjCDeclQualifier();
6237 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6238 QT = PD->getObjCDeclQualifier();
6239 if (QT == Decl::OBJC_TQ_None)
6240 return CXObjCDeclQualifier_None;
6241
6242 unsigned Result = CXObjCDeclQualifier_None;
6243 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6244 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6245 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6246 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6247 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6248 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6249
6250 return Result;
6251}
6252
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006253unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6254 if (!clang_isDeclaration(C.kind))
6255 return 0;
6256
6257 const Decl *D = getCursorDecl(C);
6258 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6259 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6260 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6261 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6262
6263 return 0;
6264}
6265
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006266unsigned clang_Cursor_isVariadic(CXCursor C) {
6267 if (!clang_isDeclaration(C.kind))
6268 return 0;
6269
6270 const Decl *D = getCursorDecl(C);
6271 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6272 return FD->isVariadic();
6273 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6274 return MD->isVariadic();
6275
6276 return 0;
6277}
6278
Guy Benyei11169dd2012-12-18 14:30:41 +00006279CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6280 if (!clang_isDeclaration(C.kind))
6281 return clang_getNullRange();
6282
6283 const Decl *D = getCursorDecl(C);
6284 ASTContext &Context = getCursorContext(C);
6285 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6286 if (!RC)
6287 return clang_getNullRange();
6288
6289 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6290}
6291
6292CXString clang_Cursor_getRawCommentText(CXCursor C) {
6293 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006294 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006295
6296 const Decl *D = getCursorDecl(C);
6297 ASTContext &Context = getCursorContext(C);
6298 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6299 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6300 StringRef();
6301
6302 // Don't duplicate the string because RawText points directly into source
6303 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006304 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006305}
6306
6307CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6308 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006309 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006310
6311 const Decl *D = getCursorDecl(C);
6312 const ASTContext &Context = getCursorContext(C);
6313 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6314
6315 if (RC) {
6316 StringRef BriefText = RC->getBriefText(Context);
6317
6318 // Don't duplicate the string because RawComment ensures that this memory
6319 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006320 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006321 }
6322
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006323 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006324}
6325
6326CXComment clang_Cursor_getParsedComment(CXCursor C) {
6327 if (!clang_isDeclaration(C.kind))
6328 return cxcomment::createCXComment(NULL, NULL);
6329
6330 const Decl *D = getCursorDecl(C);
6331 const ASTContext &Context = getCursorContext(C);
6332 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6333
6334 return cxcomment::createCXComment(FC, getCursorTU(C));
6335}
6336
6337CXModule clang_Cursor_getModule(CXCursor C) {
6338 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006339 if (const ImportDecl *ImportD =
6340 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006341 return ImportD->getImportedModule();
6342 }
6343
6344 return 0;
6345}
6346
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006347CXFile clang_Module_getASTFile(CXModule CXMod) {
6348 if (!CXMod)
6349 return 0;
6350 Module *Mod = static_cast<Module*>(CXMod);
6351 return const_cast<FileEntry *>(Mod->getASTFile());
6352}
6353
Guy Benyei11169dd2012-12-18 14:30:41 +00006354CXModule clang_Module_getParent(CXModule CXMod) {
6355 if (!CXMod)
6356 return 0;
6357 Module *Mod = static_cast<Module*>(CXMod);
6358 return Mod->Parent;
6359}
6360
6361CXString clang_Module_getName(CXModule CXMod) {
6362 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006363 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006364 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006365 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006366}
6367
6368CXString clang_Module_getFullName(CXModule CXMod) {
6369 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006370 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006371 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006372 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006373}
6374
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006375unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6376 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006377 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006378 LOG_BAD_TU(TU);
6379 return 0;
6380 }
6381 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006382 return 0;
6383 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006384 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6385 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6386 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006387}
6388
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006389CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6390 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006391 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006392 LOG_BAD_TU(TU);
6393 return 0;
6394 }
6395 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006396 return 0;
6397 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006398 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006399
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006400 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6401 if (Index < TopHeaders.size())
6402 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006403
6404 return 0;
6405}
6406
6407} // end: extern "C"
6408
6409//===----------------------------------------------------------------------===//
6410// C++ AST instrospection.
6411//===----------------------------------------------------------------------===//
6412
6413extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006414unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6415 if (!clang_isDeclaration(C.kind))
6416 return 0;
6417
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006418 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006419 const CXXMethodDecl *Method =
6420 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006421 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6422}
6423
Guy Benyei11169dd2012-12-18 14:30:41 +00006424unsigned clang_CXXMethod_isStatic(CXCursor C) {
6425 if (!clang_isDeclaration(C.kind))
6426 return 0;
6427
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006428 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006429 const CXXMethodDecl *Method =
6430 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006431 return (Method && Method->isStatic()) ? 1 : 0;
6432}
6433
6434unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6435 if (!clang_isDeclaration(C.kind))
6436 return 0;
6437
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006438 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006439 const CXXMethodDecl *Method =
6440 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006441 return (Method && Method->isVirtual()) ? 1 : 0;
6442}
6443} // end: extern "C"
6444
6445//===----------------------------------------------------------------------===//
6446// Attribute introspection.
6447//===----------------------------------------------------------------------===//
6448
6449extern "C" {
6450CXType clang_getIBOutletCollectionType(CXCursor C) {
6451 if (C.kind != CXCursor_IBOutletCollectionAttr)
6452 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6453
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006454 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006455 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6456
6457 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6458}
6459} // end: extern "C"
6460
6461//===----------------------------------------------------------------------===//
6462// Inspecting memory usage.
6463//===----------------------------------------------------------------------===//
6464
6465typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6466
6467static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6468 enum CXTUResourceUsageKind k,
6469 unsigned long amount) {
6470 CXTUResourceUsageEntry entry = { k, amount };
6471 entries.push_back(entry);
6472}
6473
6474extern "C" {
6475
6476const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6477 const char *str = "";
6478 switch (kind) {
6479 case CXTUResourceUsage_AST:
6480 str = "ASTContext: expressions, declarations, and types";
6481 break;
6482 case CXTUResourceUsage_Identifiers:
6483 str = "ASTContext: identifiers";
6484 break;
6485 case CXTUResourceUsage_Selectors:
6486 str = "ASTContext: selectors";
6487 break;
6488 case CXTUResourceUsage_GlobalCompletionResults:
6489 str = "Code completion: cached global results";
6490 break;
6491 case CXTUResourceUsage_SourceManagerContentCache:
6492 str = "SourceManager: content cache allocator";
6493 break;
6494 case CXTUResourceUsage_AST_SideTables:
6495 str = "ASTContext: side tables";
6496 break;
6497 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6498 str = "SourceManager: malloc'ed memory buffers";
6499 break;
6500 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6501 str = "SourceManager: mmap'ed memory buffers";
6502 break;
6503 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6504 str = "ExternalASTSource: malloc'ed memory buffers";
6505 break;
6506 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6507 str = "ExternalASTSource: mmap'ed memory buffers";
6508 break;
6509 case CXTUResourceUsage_Preprocessor:
6510 str = "Preprocessor: malloc'ed memory";
6511 break;
6512 case CXTUResourceUsage_PreprocessingRecord:
6513 str = "Preprocessor: PreprocessingRecord";
6514 break;
6515 case CXTUResourceUsage_SourceManager_DataStructures:
6516 str = "SourceManager: data structures and tables";
6517 break;
6518 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6519 str = "Preprocessor: header search tables";
6520 break;
6521 }
6522 return str;
6523}
6524
6525CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006526 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006527 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006528 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6529 return usage;
6530 }
6531
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006532 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006533 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6534 ASTContext &astContext = astUnit->getASTContext();
6535
6536 // How much memory is used by AST nodes and types?
6537 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6538 (unsigned long) astContext.getASTAllocatedMemory());
6539
6540 // How much memory is used by identifiers?
6541 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6542 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6543
6544 // How much memory is used for selectors?
6545 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6546 (unsigned long) astContext.Selectors.getTotalMemory());
6547
6548 // How much memory is used by ASTContext's side tables?
6549 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6550 (unsigned long) astContext.getSideTableAllocatedMemory());
6551
6552 // How much memory is used for caching global code completion results?
6553 unsigned long completionBytes = 0;
6554 if (GlobalCodeCompletionAllocator *completionAllocator =
6555 astUnit->getCachedCompletionAllocator().getPtr()) {
6556 completionBytes = completionAllocator->getTotalMemory();
6557 }
6558 createCXTUResourceUsageEntry(*entries,
6559 CXTUResourceUsage_GlobalCompletionResults,
6560 completionBytes);
6561
6562 // How much memory is being used by SourceManager's content cache?
6563 createCXTUResourceUsageEntry(*entries,
6564 CXTUResourceUsage_SourceManagerContentCache,
6565 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6566
6567 // How much memory is being used by the MemoryBuffer's in SourceManager?
6568 const SourceManager::MemoryBufferSizes &srcBufs =
6569 astUnit->getSourceManager().getMemoryBufferSizes();
6570
6571 createCXTUResourceUsageEntry(*entries,
6572 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6573 (unsigned long) srcBufs.malloc_bytes);
6574 createCXTUResourceUsageEntry(*entries,
6575 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6576 (unsigned long) srcBufs.mmap_bytes);
6577 createCXTUResourceUsageEntry(*entries,
6578 CXTUResourceUsage_SourceManager_DataStructures,
6579 (unsigned long) astContext.getSourceManager()
6580 .getDataStructureSizes());
6581
6582 // How much memory is being used by the ExternalASTSource?
6583 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6584 const ExternalASTSource::MemoryBufferSizes &sizes =
6585 esrc->getMemoryBufferSizes();
6586
6587 createCXTUResourceUsageEntry(*entries,
6588 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6589 (unsigned long) sizes.malloc_bytes);
6590 createCXTUResourceUsageEntry(*entries,
6591 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6592 (unsigned long) sizes.mmap_bytes);
6593 }
6594
6595 // How much memory is being used by the Preprocessor?
6596 Preprocessor &pp = astUnit->getPreprocessor();
6597 createCXTUResourceUsageEntry(*entries,
6598 CXTUResourceUsage_Preprocessor,
6599 pp.getTotalMemory());
6600
6601 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6602 createCXTUResourceUsageEntry(*entries,
6603 CXTUResourceUsage_PreprocessingRecord,
6604 pRec->getTotalMemory());
6605 }
6606
6607 createCXTUResourceUsageEntry(*entries,
6608 CXTUResourceUsage_Preprocessor_HeaderSearch,
6609 pp.getHeaderSearchInfo().getTotalMemory());
6610
6611 CXTUResourceUsage usage = { (void*) entries.get(),
6612 (unsigned) entries->size(),
6613 entries->size() ? &(*entries)[0] : 0 };
6614 entries.take();
6615 return usage;
6616}
6617
6618void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6619 if (usage.data)
6620 delete (MemUsageEntries*) usage.data;
6621}
6622
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006623CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6624 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006625 skipped->count = 0;
6626 skipped->ranges = 0;
6627
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006628 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006629 LOG_BAD_TU(TU);
6630 return skipped;
6631 }
6632
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006633 if (!file)
6634 return skipped;
6635
6636 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6637 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6638 if (!ppRec)
6639 return skipped;
6640
6641 ASTContext &Ctx = astUnit->getASTContext();
6642 SourceManager &sm = Ctx.getSourceManager();
6643 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6644 FileID wantedFileID = sm.translateFile(fileEntry);
6645
6646 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6647 std::vector<SourceRange> wantedRanges;
6648 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6649 i != ei; ++i) {
6650 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6651 wantedRanges.push_back(*i);
6652 }
6653
6654 skipped->count = wantedRanges.size();
6655 skipped->ranges = new CXSourceRange[skipped->count];
6656 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6657 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6658
6659 return skipped;
6660}
6661
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006662void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6663 if (ranges) {
6664 delete[] ranges->ranges;
6665 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006666 }
6667}
6668
Guy Benyei11169dd2012-12-18 14:30:41 +00006669} // end extern "C"
6670
6671void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6672 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6673 for (unsigned I = 0; I != Usage.numEntries; ++I)
6674 fprintf(stderr, " %s: %lu\n",
6675 clang_getTUResourceUsageName(Usage.entries[I].kind),
6676 Usage.entries[I].amount);
6677
6678 clang_disposeCXTUResourceUsage(Usage);
6679}
6680
6681//===----------------------------------------------------------------------===//
6682// Misc. utility functions.
6683//===----------------------------------------------------------------------===//
6684
6685/// Default to using an 8 MB stack size on "safety" threads.
6686static unsigned SafetyStackThreadSize = 8 << 20;
6687
6688namespace clang {
6689
6690bool RunSafely(llvm::CrashRecoveryContext &CRC,
6691 void (*Fn)(void*), void *UserData,
6692 unsigned Size) {
6693 if (!Size)
6694 Size = GetSafetyThreadStackSize();
6695 if (Size)
6696 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6697 return CRC.RunSafely(Fn, UserData);
6698}
6699
6700unsigned GetSafetyThreadStackSize() {
6701 return SafetyStackThreadSize;
6702}
6703
6704void SetSafetyThreadStackSize(unsigned Value) {
6705 SafetyStackThreadSize = Value;
6706}
6707
6708}
6709
6710void clang::setThreadBackgroundPriority() {
6711 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6712 return;
6713
6714 // FIXME: Move to llvm/Support and make it cross-platform.
6715#ifdef __APPLE__
6716 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6717#endif
6718}
6719
6720void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6721 if (!Unit)
6722 return;
6723
6724 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6725 DEnd = Unit->stored_diag_end();
6726 D != DEnd; ++D) {
6727 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6728 CXString Msg = clang_formatDiagnostic(&Diag,
6729 clang_defaultDiagnosticDisplayOptions());
6730 fprintf(stderr, "%s\n", clang_getCString(Msg));
6731 clang_disposeString(Msg);
6732 }
6733#ifdef LLVM_ON_WIN32
6734 // On Windows, force a flush, since there may be multiple copies of
6735 // stderr and stdout in the file system, all with different buffers
6736 // but writing to the same device.
6737 fflush(stderr);
6738#endif
6739}
6740
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006741MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6742 SourceLocation MacroDefLoc,
6743 CXTranslationUnit TU){
6744 if (MacroDefLoc.isInvalid() || !TU)
6745 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006746 if (!II.hadMacroDefinition())
6747 return 0;
6748
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006749 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006750 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006751 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006752 if (MD) {
6753 for (MacroDirective::DefInfo
6754 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6755 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6756 return Def.getMacroInfo();
6757 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006758 }
6759
6760 return 0;
6761}
6762
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006763const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6764 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006765 if (!MacroDef || !TU)
6766 return 0;
6767 const IdentifierInfo *II = MacroDef->getName();
6768 if (!II)
6769 return 0;
6770
6771 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6772}
6773
6774MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6775 const Token &Tok,
6776 CXTranslationUnit TU) {
6777 if (!MI || !TU)
6778 return 0;
6779 if (Tok.isNot(tok::raw_identifier))
6780 return 0;
6781
6782 if (MI->getNumTokens() == 0)
6783 return 0;
6784 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6785 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006786 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006787
6788 // Check that the token is inside the definition and not its argument list.
6789 SourceManager &SM = Unit->getSourceManager();
6790 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6791 return 0;
6792 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6793 return 0;
6794
6795 Preprocessor &PP = Unit->getPreprocessor();
6796 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6797 if (!PPRec)
6798 return 0;
6799
6800 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6801 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6802 if (!II.hadMacroDefinition())
6803 return 0;
6804
6805 // Check that the identifier is not one of the macro arguments.
6806 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6807 return 0;
6808
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006809 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6810 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006811 return 0;
6812
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006813 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006814}
6815
6816MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6817 SourceLocation Loc,
6818 CXTranslationUnit TU) {
6819 if (Loc.isInvalid() || !MI || !TU)
6820 return 0;
6821
6822 if (MI->getNumTokens() == 0)
6823 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006824 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006825 Preprocessor &PP = Unit->getPreprocessor();
6826 if (!PP.getPreprocessingRecord())
6827 return 0;
6828 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6829 Token Tok;
6830 if (PP.getRawToken(Loc, Tok))
6831 return 0;
6832
6833 return checkForMacroInMacroDefinition(MI, Tok, TU);
6834}
6835
Guy Benyei11169dd2012-12-18 14:30:41 +00006836extern "C" {
6837
6838CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006839 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006840}
6841
6842} // end: extern "C"
6843
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006844Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6845 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006846 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006847 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006848 if (Unit->isMainFileAST())
6849 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006850 return *this;
6851 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006852 } else {
6853 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006854 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006855 return *this;
6856}
6857
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006858Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6859 *this << FE->getName();
6860 return *this;
6861}
6862
6863Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6864 CXString cursorName = clang_getCursorDisplayName(cursor);
6865 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6866 clang_disposeString(cursorName);
6867 return *this;
6868}
6869
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006870Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6871 CXFile File;
6872 unsigned Line, Column;
6873 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6874 CXString FileName = clang_getFileName(File);
6875 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6876 clang_disposeString(FileName);
6877 return *this;
6878}
6879
6880Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6881 CXSourceLocation BLoc = clang_getRangeStart(range);
6882 CXSourceLocation ELoc = clang_getRangeEnd(range);
6883
6884 CXFile BFile;
6885 unsigned BLine, BColumn;
6886 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6887
6888 CXFile EFile;
6889 unsigned ELine, EColumn;
6890 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6891
6892 CXString BFileName = clang_getFileName(BFile);
6893 if (BFile == EFile) {
6894 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6895 BLine, BColumn, ELine, EColumn);
6896 } else {
6897 CXString EFileName = clang_getFileName(EFile);
6898 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6899 BLine, BColumn)
6900 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6901 ELine, EColumn);
6902 clang_disposeString(EFileName);
6903 }
6904 clang_disposeString(BFileName);
6905 return *this;
6906}
6907
6908Logger &cxindex::Logger::operator<<(CXString Str) {
6909 *this << clang_getCString(Str);
6910 return *this;
6911}
6912
6913Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6914 LogOS << Fmt;
6915 return *this;
6916}
6917
6918cxindex::Logger::~Logger() {
6919 LogOS.flush();
6920
6921 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6922
6923 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6924
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006925 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006926 OS << "[libclang:" << Name << ':';
6927
6928 // FIXME: Portability.
6929#if HAVE_PTHREAD_H && __APPLE__
6930 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6931 OS << tid << ':';
6932#endif
6933
6934 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6935 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6936 OS << Msg.str() << '\n';
6937
6938 if (Trace) {
6939 llvm::sys::PrintStackTrace(stderr);
6940 OS << "--------------------------------------------------\n";
6941 }
6942}