blob: 52a792927efdb9c51bcf20489efb5eaf78b53574 [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
Aaron Ballman43b68be2014-03-07 17:50:17 +0000919 for (const auto *P : ND->params()) {
920 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000921 return true;
922 }
923
924 if (ND->isThisDeclarationADefinition() &&
925 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
926 return true;
927
928 return false;
929}
930
931template <typename DeclIt>
932static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
933 SourceManager &SM, SourceLocation EndLoc,
934 SmallVectorImpl<Decl *> &Decls) {
935 DeclIt next = *DI_current;
936 while (++next != DE_current) {
937 Decl *D_next = *next;
938 if (!D_next)
939 break;
940 SourceLocation L = D_next->getLocStart();
941 if (!L.isValid())
942 break;
943 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
944 *DI_current = next;
945 Decls.push_back(D_next);
946 continue;
947 }
948 break;
949 }
950}
951
Guy Benyei11169dd2012-12-18 14:30:41 +0000952bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
953 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
954 // an @implementation can lexically contain Decls that are not properly
955 // nested in the AST. When we identify such cases, we need to retrofit
956 // this nesting here.
957 if (!DI_current && !FileDI_current)
958 return VisitDeclContext(D);
959
960 // Scan the Decls that immediately come after the container
961 // in the current DeclContext. If any fall within the
962 // container's lexical region, stash them into a vector
963 // for later processing.
964 SmallVector<Decl *, 24> DeclsInContainer;
965 SourceLocation EndLoc = D->getSourceRange().getEnd();
966 SourceManager &SM = AU->getSourceManager();
967 if (EndLoc.isValid()) {
968 if (DI_current) {
969 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
970 DeclsInContainer);
971 } else {
972 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
973 DeclsInContainer);
974 }
975 }
976
977 // The common case.
978 if (DeclsInContainer.empty())
979 return VisitDeclContext(D);
980
981 // Get all the Decls in the DeclContext, and sort them with the
982 // additional ones we've collected. Then visit them.
983 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
984 I!=E; ++I) {
985 Decl *subDecl = *I;
986 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
987 subDecl->getLocStart().isInvalid())
988 continue;
989 DeclsInContainer.push_back(subDecl);
990 }
991
992 // Now sort the Decls so that they appear in lexical order.
993 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000994 [&SM](Decl *A, Decl *B) {
995 SourceLocation L_A = A->getLocStart();
996 SourceLocation L_B = B->getLocStart();
997 assert(L_A.isValid() && L_B.isValid());
998 return SM.isBeforeInTranslationUnit(L_A, L_B);
999 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001000
1001 // Now visit the decls.
1002 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1003 E = DeclsInContainer.end(); I != E; ++I) {
1004 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001005 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001006 if (!V.hasValue())
1007 continue;
1008 if (!V.getValue())
1009 return false;
1010 if (Visit(Cursor, true))
1011 return true;
1012 }
1013 return false;
1014}
1015
1016bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1017 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1018 TU)))
1019 return true;
1020
1021 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1022 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1023 E = ND->protocol_end(); I != E; ++I, ++PL)
1024 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1025 return true;
1026
1027 return VisitObjCContainerDecl(ND);
1028}
1029
1030bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1031 if (!PID->isThisDeclarationADefinition())
1032 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1033
1034 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1035 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1036 E = PID->protocol_end(); I != E; ++I, ++PL)
1037 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1038 return true;
1039
1040 return VisitObjCContainerDecl(PID);
1041}
1042
1043bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1044 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1045 return true;
1046
1047 // FIXME: This implements a workaround with @property declarations also being
1048 // installed in the DeclContext for the @interface. Eventually this code
1049 // should be removed.
1050 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1051 if (!CDecl || !CDecl->IsClassExtension())
1052 return false;
1053
1054 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1055 if (!ID)
1056 return false;
1057
1058 IdentifierInfo *PropertyId = PD->getIdentifier();
1059 ObjCPropertyDecl *prevDecl =
1060 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1061
1062 if (!prevDecl)
1063 return false;
1064
1065 // Visit synthesized methods since they will be skipped when visiting
1066 // the @interface.
1067 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1068 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1069 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1070 return true;
1071
1072 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1073 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1074 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1075 return true;
1076
1077 return false;
1078}
1079
1080bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1081 if (!D->isThisDeclarationADefinition()) {
1082 // Forward declaration is treated like a reference.
1083 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1084 }
1085
1086 // Issue callbacks for super class.
1087 if (D->getSuperClass() &&
1088 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1089 D->getSuperClassLoc(),
1090 TU)))
1091 return true;
1092
1093 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1094 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1095 E = D->protocol_end(); I != E; ++I, ++PL)
1096 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1097 return true;
1098
1099 return VisitObjCContainerDecl(D);
1100}
1101
1102bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1103 return VisitObjCContainerDecl(D);
1104}
1105
1106bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1107 // 'ID' could be null when dealing with invalid code.
1108 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1109 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1110 return true;
1111
1112 return VisitObjCImplDecl(D);
1113}
1114
1115bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1116#if 0
1117 // Issue callbacks for super class.
1118 // FIXME: No source location information!
1119 if (D->getSuperClass() &&
1120 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1121 D->getSuperClassLoc(),
1122 TU)))
1123 return true;
1124#endif
1125
1126 return VisitObjCImplDecl(D);
1127}
1128
1129bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1130 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1131 if (PD->isIvarNameSpecified())
1132 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1133
1134 return false;
1135}
1136
1137bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1138 return VisitDeclContext(D);
1139}
1140
1141bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1142 // Visit nested-name-specifier.
1143 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1144 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1145 return true;
1146
1147 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1148 D->getTargetNameLoc(), TU));
1149}
1150
1151bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1152 // Visit nested-name-specifier.
1153 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1154 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1155 return true;
1156 }
1157
1158 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1159 return true;
1160
1161 return VisitDeclarationNameInfo(D->getNameInfo());
1162}
1163
1164bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1165 // Visit nested-name-specifier.
1166 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1167 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1168 return true;
1169
1170 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1171 D->getIdentLocation(), TU));
1172}
1173
1174bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1175 // Visit nested-name-specifier.
1176 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1177 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1178 return true;
1179 }
1180
1181 return VisitDeclarationNameInfo(D->getNameInfo());
1182}
1183
1184bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1185 UnresolvedUsingTypenameDecl *D) {
1186 // Visit nested-name-specifier.
1187 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1188 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1189 return true;
1190
1191 return false;
1192}
1193
1194bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1195 switch (Name.getName().getNameKind()) {
1196 case clang::DeclarationName::Identifier:
1197 case clang::DeclarationName::CXXLiteralOperatorName:
1198 case clang::DeclarationName::CXXOperatorName:
1199 case clang::DeclarationName::CXXUsingDirective:
1200 return false;
1201
1202 case clang::DeclarationName::CXXConstructorName:
1203 case clang::DeclarationName::CXXDestructorName:
1204 case clang::DeclarationName::CXXConversionFunctionName:
1205 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1206 return Visit(TSInfo->getTypeLoc());
1207 return false;
1208
1209 case clang::DeclarationName::ObjCZeroArgSelector:
1210 case clang::DeclarationName::ObjCOneArgSelector:
1211 case clang::DeclarationName::ObjCMultiArgSelector:
1212 // FIXME: Per-identifier location info?
1213 return false;
1214 }
1215
1216 llvm_unreachable("Invalid DeclarationName::Kind!");
1217}
1218
1219bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1220 SourceRange Range) {
1221 // FIXME: This whole routine is a hack to work around the lack of proper
1222 // source information in nested-name-specifiers (PR5791). Since we do have
1223 // a beginning source location, we can visit the first component of the
1224 // nested-name-specifier, if it's a single-token component.
1225 if (!NNS)
1226 return false;
1227
1228 // Get the first component in the nested-name-specifier.
1229 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1230 NNS = Prefix;
1231
1232 switch (NNS->getKind()) {
1233 case NestedNameSpecifier::Namespace:
1234 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1235 TU));
1236
1237 case NestedNameSpecifier::NamespaceAlias:
1238 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1239 Range.getBegin(), TU));
1240
1241 case NestedNameSpecifier::TypeSpec: {
1242 // If the type has a form where we know that the beginning of the source
1243 // range matches up with a reference cursor. Visit the appropriate reference
1244 // cursor.
1245 const Type *T = NNS->getAsType();
1246 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1247 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1248 if (const TagType *Tag = dyn_cast<TagType>(T))
1249 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1250 if (const TemplateSpecializationType *TST
1251 = dyn_cast<TemplateSpecializationType>(T))
1252 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1253 break;
1254 }
1255
1256 case NestedNameSpecifier::TypeSpecWithTemplate:
1257 case NestedNameSpecifier::Global:
1258 case NestedNameSpecifier::Identifier:
1259 break;
1260 }
1261
1262 return false;
1263}
1264
1265bool
1266CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1267 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1268 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1269 Qualifiers.push_back(Qualifier);
1270
1271 while (!Qualifiers.empty()) {
1272 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1273 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1274 switch (NNS->getKind()) {
1275 case NestedNameSpecifier::Namespace:
1276 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1277 Q.getLocalBeginLoc(),
1278 TU)))
1279 return true;
1280
1281 break;
1282
1283 case NestedNameSpecifier::NamespaceAlias:
1284 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1285 Q.getLocalBeginLoc(),
1286 TU)))
1287 return true;
1288
1289 break;
1290
1291 case NestedNameSpecifier::TypeSpec:
1292 case NestedNameSpecifier::TypeSpecWithTemplate:
1293 if (Visit(Q.getTypeLoc()))
1294 return true;
1295
1296 break;
1297
1298 case NestedNameSpecifier::Global:
1299 case NestedNameSpecifier::Identifier:
1300 break;
1301 }
1302 }
1303
1304 return false;
1305}
1306
1307bool CursorVisitor::VisitTemplateParameters(
1308 const TemplateParameterList *Params) {
1309 if (!Params)
1310 return false;
1311
1312 for (TemplateParameterList::const_iterator P = Params->begin(),
1313 PEnd = Params->end();
1314 P != PEnd; ++P) {
1315 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1316 return true;
1317 }
1318
1319 return false;
1320}
1321
1322bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1323 switch (Name.getKind()) {
1324 case TemplateName::Template:
1325 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1326
1327 case TemplateName::OverloadedTemplate:
1328 // Visit the overloaded template set.
1329 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1330 return true;
1331
1332 return false;
1333
1334 case TemplateName::DependentTemplate:
1335 // FIXME: Visit nested-name-specifier.
1336 return false;
1337
1338 case TemplateName::QualifiedTemplate:
1339 // FIXME: Visit nested-name-specifier.
1340 return Visit(MakeCursorTemplateRef(
1341 Name.getAsQualifiedTemplateName()->getDecl(),
1342 Loc, TU));
1343
1344 case TemplateName::SubstTemplateTemplateParm:
1345 return Visit(MakeCursorTemplateRef(
1346 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1347 Loc, TU));
1348
1349 case TemplateName::SubstTemplateTemplateParmPack:
1350 return Visit(MakeCursorTemplateRef(
1351 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1352 Loc, TU));
1353 }
1354
1355 llvm_unreachable("Invalid TemplateName::Kind!");
1356}
1357
1358bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1359 switch (TAL.getArgument().getKind()) {
1360 case TemplateArgument::Null:
1361 case TemplateArgument::Integral:
1362 case TemplateArgument::Pack:
1363 return false;
1364
1365 case TemplateArgument::Type:
1366 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1367 return Visit(TSInfo->getTypeLoc());
1368 return false;
1369
1370 case TemplateArgument::Declaration:
1371 if (Expr *E = TAL.getSourceDeclExpression())
1372 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1373 return false;
1374
1375 case TemplateArgument::NullPtr:
1376 if (Expr *E = TAL.getSourceNullPtrExpression())
1377 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1378 return false;
1379
1380 case TemplateArgument::Expression:
1381 if (Expr *E = TAL.getSourceExpression())
1382 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1383 return false;
1384
1385 case TemplateArgument::Template:
1386 case TemplateArgument::TemplateExpansion:
1387 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1388 return true;
1389
1390 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1391 TAL.getTemplateNameLoc());
1392 }
1393
1394 llvm_unreachable("Invalid TemplateArgument::Kind!");
1395}
1396
1397bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1398 return VisitDeclContext(D);
1399}
1400
1401bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1402 return Visit(TL.getUnqualifiedLoc());
1403}
1404
1405bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1406 ASTContext &Context = AU->getASTContext();
1407
1408 // Some builtin types (such as Objective-C's "id", "sel", and
1409 // "Class") have associated declarations. Create cursors for those.
1410 QualType VisitType;
1411 switch (TL.getTypePtr()->getKind()) {
1412
1413 case BuiltinType::Void:
1414 case BuiltinType::NullPtr:
1415 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001416 case BuiltinType::OCLImage1d:
1417 case BuiltinType::OCLImage1dArray:
1418 case BuiltinType::OCLImage1dBuffer:
1419 case BuiltinType::OCLImage2d:
1420 case BuiltinType::OCLImage2dArray:
1421 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001422 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001423 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001424#define BUILTIN_TYPE(Id, SingletonId)
1425#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1426#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1427#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1428#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1429#include "clang/AST/BuiltinTypes.def"
1430 break;
1431
1432 case BuiltinType::ObjCId:
1433 VisitType = Context.getObjCIdType();
1434 break;
1435
1436 case BuiltinType::ObjCClass:
1437 VisitType = Context.getObjCClassType();
1438 break;
1439
1440 case BuiltinType::ObjCSel:
1441 VisitType = Context.getObjCSelType();
1442 break;
1443 }
1444
1445 if (!VisitType.isNull()) {
1446 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1447 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1448 TU));
1449 }
1450
1451 return false;
1452}
1453
1454bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1455 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1456}
1457
1458bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1459 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1460}
1461
1462bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1463 if (TL.isDefinition())
1464 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1465
1466 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1467}
1468
1469bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1470 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1471}
1472
1473bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1474 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1475 return true;
1476
1477 return false;
1478}
1479
1480bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1481 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1482 return true;
1483
1484 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1485 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1486 TU)))
1487 return true;
1488 }
1489
1490 return false;
1491}
1492
1493bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1494 return Visit(TL.getPointeeLoc());
1495}
1496
1497bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1498 return Visit(TL.getInnerLoc());
1499}
1500
1501bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1502 return Visit(TL.getPointeeLoc());
1503}
1504
1505bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1506 return Visit(TL.getPointeeLoc());
1507}
1508
1509bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1510 return Visit(TL.getPointeeLoc());
1511}
1512
1513bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1514 return Visit(TL.getPointeeLoc());
1515}
1516
1517bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1518 return Visit(TL.getPointeeLoc());
1519}
1520
1521bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1522 return Visit(TL.getModifiedLoc());
1523}
1524
1525bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1526 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001527 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001528 return true;
1529
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001530 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1531 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001532 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1533 return true;
1534
1535 return false;
1536}
1537
1538bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1539 if (Visit(TL.getElementLoc()))
1540 return true;
1541
1542 if (Expr *Size = TL.getSizeExpr())
1543 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1544
1545 return false;
1546}
1547
Reid Kleckner8a365022013-06-24 17:51:48 +00001548bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1549 return Visit(TL.getOriginalLoc());
1550}
1551
Reid Kleckner0503a872013-12-05 01:23:43 +00001552bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1553 return Visit(TL.getOriginalLoc());
1554}
1555
Guy Benyei11169dd2012-12-18 14:30:41 +00001556bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1557 TemplateSpecializationTypeLoc TL) {
1558 // Visit the template name.
1559 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1560 TL.getTemplateNameLoc()))
1561 return true;
1562
1563 // Visit the template arguments.
1564 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1565 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1566 return true;
1567
1568 return false;
1569}
1570
1571bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1572 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1573}
1574
1575bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1576 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1577 return Visit(TSInfo->getTypeLoc());
1578
1579 return false;
1580}
1581
1582bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1583 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1584 return Visit(TSInfo->getTypeLoc());
1585
1586 return false;
1587}
1588
1589bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1590 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1591 return true;
1592
1593 return false;
1594}
1595
1596bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1597 DependentTemplateSpecializationTypeLoc TL) {
1598 // Visit the nested-name-specifier, if there is one.
1599 if (TL.getQualifierLoc() &&
1600 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1601 return true;
1602
1603 // Visit the template arguments.
1604 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1605 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1606 return true;
1607
1608 return false;
1609}
1610
1611bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1612 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1613 return true;
1614
1615 return Visit(TL.getNamedTypeLoc());
1616}
1617
1618bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1619 return Visit(TL.getPatternLoc());
1620}
1621
1622bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1623 if (Expr *E = TL.getUnderlyingExpr())
1624 return Visit(MakeCXCursor(E, StmtParent, TU));
1625
1626 return false;
1627}
1628
1629bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1630 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1631}
1632
1633bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1634 return Visit(TL.getValueLoc());
1635}
1636
1637#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1638bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1639 return Visit##PARENT##Loc(TL); \
1640}
1641
1642DEFAULT_TYPELOC_IMPL(Complex, Type)
1643DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1644DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1645DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1646DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1647DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1648DEFAULT_TYPELOC_IMPL(Vector, Type)
1649DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1650DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1651DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1652DEFAULT_TYPELOC_IMPL(Record, TagType)
1653DEFAULT_TYPELOC_IMPL(Enum, TagType)
1654DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1655DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1656DEFAULT_TYPELOC_IMPL(Auto, Type)
1657
1658bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1659 // Visit the nested-name-specifier, if present.
1660 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1661 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1662 return true;
1663
1664 if (D->isCompleteDefinition()) {
1665 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1666 E = D->bases_end(); I != E; ++I) {
1667 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1668 return true;
1669 }
1670 }
1671
1672 return VisitTagDecl(D);
1673}
1674
1675bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballman7dce1a82014-03-07 13:13:38 +00001676 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1677 i != e; ++i)
1678 if (Visit(MakeCXCursor(*i, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001679 return true;
1680
1681 return false;
1682}
1683
1684//===----------------------------------------------------------------------===//
1685// Data-recursive visitor methods.
1686//===----------------------------------------------------------------------===//
1687
1688namespace {
1689#define DEF_JOB(NAME, DATA, KIND)\
1690class NAME : public VisitorJob {\
1691public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001692 NAME(const DATA *d, CXCursor parent) : \
1693 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001694 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001695 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001696};
1697
1698DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1699DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1700DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1701DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1702DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1703 ExplicitTemplateArgsVisitKind)
1704DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1705DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1706DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1707#undef DEF_JOB
1708
1709class DeclVisit : public VisitorJob {
1710public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001711 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001712 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001713 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001714 static bool classof(const VisitorJob *VJ) {
1715 return VJ->getKind() == DeclVisitKind;
1716 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001717 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001718 bool isFirst() const { return data[1] ? true : false; }
1719};
1720class TypeLocVisit : public VisitorJob {
1721public:
1722 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1723 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1724 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1725
1726 static bool classof(const VisitorJob *VJ) {
1727 return VJ->getKind() == TypeLocVisitKind;
1728 }
1729
1730 TypeLoc get() const {
1731 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001732 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001733 }
1734};
1735
1736class LabelRefVisit : public VisitorJob {
1737public:
1738 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1739 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1740 labelLoc.getPtrEncoding()) {}
1741
1742 static bool classof(const VisitorJob *VJ) {
1743 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1744 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001745 const LabelDecl *get() const {
1746 return static_cast<const LabelDecl *>(data[0]);
1747 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001748 SourceLocation getLoc() const {
1749 return SourceLocation::getFromPtrEncoding(data[1]); }
1750};
1751
1752class NestedNameSpecifierLocVisit : public VisitorJob {
1753public:
1754 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1755 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1756 Qualifier.getNestedNameSpecifier(),
1757 Qualifier.getOpaqueData()) { }
1758
1759 static bool classof(const VisitorJob *VJ) {
1760 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1761 }
1762
1763 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001764 return NestedNameSpecifierLoc(
1765 const_cast<NestedNameSpecifier *>(
1766 static_cast<const NestedNameSpecifier *>(data[0])),
1767 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001768 }
1769};
1770
1771class DeclarationNameInfoVisit : public VisitorJob {
1772public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001773 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001774 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001775 static bool classof(const VisitorJob *VJ) {
1776 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1777 }
1778 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001779 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001780 switch (S->getStmtClass()) {
1781 default:
1782 llvm_unreachable("Unhandled Stmt");
1783 case clang::Stmt::MSDependentExistsStmtClass:
1784 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1785 case Stmt::CXXDependentScopeMemberExprClass:
1786 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1787 case Stmt::DependentScopeDeclRefExprClass:
1788 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1789 }
1790 }
1791};
1792class MemberRefVisit : public VisitorJob {
1793public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001794 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001795 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1796 L.getPtrEncoding()) {}
1797 static bool classof(const VisitorJob *VJ) {
1798 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1799 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001800 const FieldDecl *get() const {
1801 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001802 }
1803 SourceLocation getLoc() const {
1804 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1805 }
1806};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001807class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001808 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001809 VisitorWorkList &WL;
1810 CXCursor Parent;
1811public:
1812 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1813 : WL(wl), Parent(parent) {}
1814
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001815 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1816 void VisitBlockExpr(const BlockExpr *B);
1817 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1818 void VisitCompoundStmt(const CompoundStmt *S);
1819 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1820 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1821 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1822 void VisitCXXNewExpr(const CXXNewExpr *E);
1823 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1824 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1825 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1826 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1827 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1828 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1829 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1830 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1831 void VisitDeclRefExpr(const DeclRefExpr *D);
1832 void VisitDeclStmt(const DeclStmt *S);
1833 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1834 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1835 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1836 void VisitForStmt(const ForStmt *FS);
1837 void VisitGotoStmt(const GotoStmt *GS);
1838 void VisitIfStmt(const IfStmt *If);
1839 void VisitInitListExpr(const InitListExpr *IE);
1840 void VisitMemberExpr(const MemberExpr *M);
1841 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1842 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1843 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1844 void VisitOverloadExpr(const OverloadExpr *E);
1845 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1846 void VisitStmt(const Stmt *S);
1847 void VisitSwitchStmt(const SwitchStmt *S);
1848 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001849 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1850 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1851 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1852 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1853 void VisitVAArgExpr(const VAArgExpr *E);
1854 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1855 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1856 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1857 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001858 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1859 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001860 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001861
Guy Benyei11169dd2012-12-18 14:30:41 +00001862private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001863 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001864 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1865 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001866 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1867 void AddStmt(const Stmt *S);
1868 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001869 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001870 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001871 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001872};
1873} // end anonyous namespace
1874
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001875void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001876 // 'S' should always be non-null, since it comes from the
1877 // statement we are visiting.
1878 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1879}
1880
1881void
1882EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1883 if (Qualifier)
1884 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1885}
1886
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001887void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001888 if (S)
1889 WL.push_back(StmtVisit(S, Parent));
1890}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001891void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001892 if (D)
1893 WL.push_back(DeclVisit(D, Parent, isFirst));
1894}
1895void EnqueueVisitor::
1896 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1897 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001898 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001899}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001900void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001901 if (D)
1902 WL.push_back(MemberRefVisit(D, L, Parent));
1903}
1904void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1905 if (TI)
1906 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1907 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001908void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001909 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001910 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001911 AddStmt(*Child);
1912 }
1913 if (size == WL.size())
1914 return;
1915 // Now reverse the entries we just added. This will match the DFS
1916 // ordering performed by the worklist.
1917 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1918 std::reverse(I, E);
1919}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001920namespace {
1921class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1922 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001923 /// \brief Process clauses with list of variables.
1924 template <typename T>
1925 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001926public:
1927 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1928#define OPENMP_CLAUSE(Name, Class) \
1929 void Visit##Class(const Class *C);
1930#include "clang/Basic/OpenMPKinds.def"
1931};
1932
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001933void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1934 Visitor->AddStmt(C->getCondition());
1935}
1936
Alexey Bataev568a8332014-03-06 06:15:19 +00001937void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1938 Visitor->AddStmt(C->getNumThreads());
1939}
1940
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001941void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001942
1943template<typename T>
1944void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
1945 for (typename T::varlist_const_iterator I = Node->varlist_begin(),
1946 E = Node->varlist_end();
1947 I != E; ++I)
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001948 Visitor->AddStmt(*I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001949}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001950
1951void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001952 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001953}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001954void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1955 const OMPFirstprivateClause *C) {
1956 VisitOMPClauseList(C);
1957}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001958void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001959 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001960}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001961}
Alexey Bataev756c1962013-09-24 03:17:45 +00001962
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001963void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1964 unsigned size = WL.size();
1965 OMPClauseEnqueue Visitor(this);
1966 Visitor.Visit(S);
1967 if (size == WL.size())
1968 return;
1969 // Now reverse the entries we just added. This will match the DFS
1970 // ordering performed by the worklist.
1971 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1972 std::reverse(I, E);
1973}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001974void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001975 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1976}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001977void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001978 AddDecl(B->getBlockDecl());
1979}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001980void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001981 EnqueueChildren(E);
1982 AddTypeLoc(E->getTypeSourceInfo());
1983}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001984void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1985 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001986 E = S->body_rend(); I != E; ++I) {
1987 AddStmt(*I);
1988 }
1989}
1990void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001991VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001992 AddStmt(S->getSubStmt());
1993 AddDeclarationNameInfo(S);
1994 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1995 AddNestedNameSpecifierLoc(QualifierLoc);
1996}
1997
1998void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001999VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002000 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2001 AddDeclarationNameInfo(E);
2002 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2003 AddNestedNameSpecifierLoc(QualifierLoc);
2004 if (!E->isImplicitAccess())
2005 AddStmt(E->getBase());
2006}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002007void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002008 // Enqueue the initializer , if any.
2009 AddStmt(E->getInitializer());
2010 // Enqueue the array size, if any.
2011 AddStmt(E->getArraySize());
2012 // Enqueue the allocated type.
2013 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2014 // Enqueue the placement arguments.
2015 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2016 AddStmt(E->getPlacementArg(I-1));
2017}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002018void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002019 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2020 AddStmt(CE->getArg(I-1));
2021 AddStmt(CE->getCallee());
2022 AddStmt(CE->getArg(0));
2023}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002024void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2025 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002026 // Visit the name of the type being destroyed.
2027 AddTypeLoc(E->getDestroyedTypeInfo());
2028 // Visit the scope type that looks disturbingly like the nested-name-specifier
2029 // but isn't.
2030 AddTypeLoc(E->getScopeTypeInfo());
2031 // Visit the nested-name-specifier.
2032 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2033 AddNestedNameSpecifierLoc(QualifierLoc);
2034 // Visit base expression.
2035 AddStmt(E->getBase());
2036}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002037void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2038 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002039 AddTypeLoc(E->getTypeSourceInfo());
2040}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002041void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2042 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002043 EnqueueChildren(E);
2044 AddTypeLoc(E->getTypeSourceInfo());
2045}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002046void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002047 EnqueueChildren(E);
2048 if (E->isTypeOperand())
2049 AddTypeLoc(E->getTypeOperandSourceInfo());
2050}
2051
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002052void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2053 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002054 EnqueueChildren(E);
2055 AddTypeLoc(E->getTypeSourceInfo());
2056}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002057void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002058 EnqueueChildren(E);
2059 if (E->isTypeOperand())
2060 AddTypeLoc(E->getTypeOperandSourceInfo());
2061}
2062
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002063void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002064 EnqueueChildren(S);
2065 AddDecl(S->getExceptionDecl());
2066}
2067
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002068void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002069 if (DR->hasExplicitTemplateArgs()) {
2070 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2071 }
2072 WL.push_back(DeclRefExprParts(DR, Parent));
2073}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002074void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2075 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002076 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2077 AddDeclarationNameInfo(E);
2078 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2079}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002080void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002081 unsigned size = WL.size();
2082 bool isFirst = true;
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002083 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00002084 D != DEnd; ++D) {
2085 AddDecl(*D, isFirst);
2086 isFirst = false;
2087 }
2088 if (size == WL.size())
2089 return;
2090 // Now reverse the entries we just added. This will match the DFS
2091 // ordering performed by the worklist.
2092 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2093 std::reverse(I, E);
2094}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002095void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002096 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002097 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002098 D = E->designators_rbegin(), DEnd = E->designators_rend();
2099 D != DEnd; ++D) {
2100 if (D->isFieldDesignator()) {
2101 if (FieldDecl *Field = D->getField())
2102 AddMemberRef(Field, D->getFieldLoc());
2103 continue;
2104 }
2105 if (D->isArrayDesignator()) {
2106 AddStmt(E->getArrayIndex(*D));
2107 continue;
2108 }
2109 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2110 AddStmt(E->getArrayRangeEnd(*D));
2111 AddStmt(E->getArrayRangeStart(*D));
2112 }
2113}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002114void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002115 EnqueueChildren(E);
2116 AddTypeLoc(E->getTypeInfoAsWritten());
2117}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002118void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002119 AddStmt(FS->getBody());
2120 AddStmt(FS->getInc());
2121 AddStmt(FS->getCond());
2122 AddDecl(FS->getConditionVariable());
2123 AddStmt(FS->getInit());
2124}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002125void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002126 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2127}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002128void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002129 AddStmt(If->getElse());
2130 AddStmt(If->getThen());
2131 AddStmt(If->getCond());
2132 AddDecl(If->getConditionVariable());
2133}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002134void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002135 // We care about the syntactic form of the initializer list, only.
2136 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2137 IE = Syntactic;
2138 EnqueueChildren(IE);
2139}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002140void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002141 WL.push_back(MemberExprParts(M, Parent));
2142
2143 // If the base of the member access expression is an implicit 'this', don't
2144 // visit it.
2145 // FIXME: If we ever want to show these implicit accesses, this will be
2146 // unfortunate. However, clang_getCursor() relies on this behavior.
2147 if (!M->isImplicitAccess())
2148 AddStmt(M->getBase());
2149}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002150void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002151 AddTypeLoc(E->getEncodedTypeSourceInfo());
2152}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002153void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002154 EnqueueChildren(M);
2155 AddTypeLoc(M->getClassReceiverTypeInfo());
2156}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002157void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002158 // Visit the components of the offsetof expression.
2159 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2160 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2161 const OffsetOfNode &Node = E->getComponent(I-1);
2162 switch (Node.getKind()) {
2163 case OffsetOfNode::Array:
2164 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2165 break;
2166 case OffsetOfNode::Field:
2167 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2168 break;
2169 case OffsetOfNode::Identifier:
2170 case OffsetOfNode::Base:
2171 continue;
2172 }
2173 }
2174 // Visit the type into which we're computing the offset.
2175 AddTypeLoc(E->getTypeSourceInfo());
2176}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002177void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002178 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2179 WL.push_back(OverloadExprParts(E, Parent));
2180}
2181void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002182 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002183 EnqueueChildren(E);
2184 if (E->isArgumentType())
2185 AddTypeLoc(E->getArgumentTypeInfo());
2186}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002187void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002188 EnqueueChildren(S);
2189}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002190void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002191 AddStmt(S->getBody());
2192 AddStmt(S->getCond());
2193 AddDecl(S->getConditionVariable());
2194}
2195
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002196void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002197 AddStmt(W->getBody());
2198 AddStmt(W->getCond());
2199 AddDecl(W->getConditionVariable());
2200}
2201
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002202void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002203 for (unsigned I = E->getNumArgs(); I > 0; --I)
2204 AddTypeLoc(E->getArg(I-1));
2205}
2206
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002207void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002208 AddTypeLoc(E->getQueriedTypeSourceInfo());
2209}
2210
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002212 EnqueueChildren(E);
2213}
2214
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002215void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002216 VisitOverloadExpr(U);
2217 if (!U->isImplicitAccess())
2218 AddStmt(U->getBase());
2219}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002220void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002221 AddStmt(E->getSubExpr());
2222 AddTypeLoc(E->getWrittenTypeInfo());
2223}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002224void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002225 WL.push_back(SizeOfPackExprParts(E, Parent));
2226}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002227void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002228 // If the opaque value has a source expression, just transparently
2229 // visit that. This is useful for (e.g.) pseudo-object expressions.
2230 if (Expr *SourceExpr = E->getSourceExpr())
2231 return Visit(SourceExpr);
2232}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002233void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002234 AddStmt(E->getBody());
2235 WL.push_back(LambdaExprParts(E, Parent));
2236}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002237void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002238 // Treat the expression like its syntactic form.
2239 Visit(E->getSyntacticForm());
2240}
2241
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002242void EnqueueVisitor::VisitOMPExecutableDirective(
2243 const OMPExecutableDirective *D) {
2244 EnqueueChildren(D);
2245 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2246 E = D->clauses().end();
2247 I != E; ++I)
2248 EnqueueChildren(*I);
2249}
2250
2251void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2252 VisitOMPExecutableDirective(D);
2253}
2254
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002255void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2256 VisitOMPExecutableDirective(D);
2257}
2258
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002259void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002260 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2261}
2262
2263bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2264 if (RegionOfInterest.isValid()) {
2265 SourceRange Range = getRawCursorExtent(C);
2266 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2267 return false;
2268 }
2269 return true;
2270}
2271
2272bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2273 while (!WL.empty()) {
2274 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002275 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002276
2277 // Set the Parent field, then back to its old value once we're done.
2278 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2279
2280 switch (LI.getKind()) {
2281 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002282 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002283 if (!D)
2284 continue;
2285
2286 // For now, perform default visitation for Decls.
2287 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2288 cast<DeclVisit>(&LI)->isFirst())))
2289 return true;
2290
2291 continue;
2292 }
2293 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2294 const ASTTemplateArgumentListInfo *ArgList =
2295 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2296 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2297 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2298 Arg != ArgEnd; ++Arg) {
2299 if (VisitTemplateArgumentLoc(*Arg))
2300 return true;
2301 }
2302 continue;
2303 }
2304 case VisitorJob::TypeLocVisitKind: {
2305 // Perform default visitation for TypeLocs.
2306 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2307 return true;
2308 continue;
2309 }
2310 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002311 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002312 if (LabelStmt *stmt = LS->getStmt()) {
2313 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2314 TU))) {
2315 return true;
2316 }
2317 }
2318 continue;
2319 }
2320
2321 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2322 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2323 if (VisitNestedNameSpecifierLoc(V->get()))
2324 return true;
2325 continue;
2326 }
2327
2328 case VisitorJob::DeclarationNameInfoVisitKind: {
2329 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2330 ->get()))
2331 return true;
2332 continue;
2333 }
2334 case VisitorJob::MemberRefVisitKind: {
2335 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2336 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2337 return true;
2338 continue;
2339 }
2340 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002341 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002342 if (!S)
2343 continue;
2344
2345 // Update the current cursor.
2346 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2347 if (!IsInRegionOfInterest(Cursor))
2348 continue;
2349 switch (Visitor(Cursor, Parent, ClientData)) {
2350 case CXChildVisit_Break: return true;
2351 case CXChildVisit_Continue: break;
2352 case CXChildVisit_Recurse:
2353 if (PostChildrenVisitor)
2354 WL.push_back(PostChildrenVisit(0, Cursor));
2355 EnqueueWorkList(WL, S);
2356 break;
2357 }
2358 continue;
2359 }
2360 case VisitorJob::MemberExprPartsKind: {
2361 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002362 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002363
2364 // Visit the nested-name-specifier
2365 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2366 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2367 return true;
2368
2369 // Visit the declaration name.
2370 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2371 return true;
2372
2373 // Visit the explicitly-specified template arguments, if any.
2374 if (M->hasExplicitTemplateArgs()) {
2375 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2376 *ArgEnd = Arg + M->getNumTemplateArgs();
2377 Arg != ArgEnd; ++Arg) {
2378 if (VisitTemplateArgumentLoc(*Arg))
2379 return true;
2380 }
2381 }
2382 continue;
2383 }
2384 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002385 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002386 // Visit nested-name-specifier, if present.
2387 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2388 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2389 return true;
2390 // Visit declaration name.
2391 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2392 return true;
2393 continue;
2394 }
2395 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002396 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002397 // Visit the nested-name-specifier.
2398 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2399 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2400 return true;
2401 // Visit the declaration name.
2402 if (VisitDeclarationNameInfo(O->getNameInfo()))
2403 return true;
2404 // Visit the overloaded declaration reference.
2405 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2406 return true;
2407 continue;
2408 }
2409 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002410 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002411 NamedDecl *Pack = E->getPack();
2412 if (isa<TemplateTypeParmDecl>(Pack)) {
2413 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2414 E->getPackLoc(), TU)))
2415 return true;
2416
2417 continue;
2418 }
2419
2420 if (isa<TemplateTemplateParmDecl>(Pack)) {
2421 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2422 E->getPackLoc(), TU)))
2423 return true;
2424
2425 continue;
2426 }
2427
2428 // Non-type template parameter packs and function parameter packs are
2429 // treated like DeclRefExpr cursors.
2430 continue;
2431 }
2432
2433 case VisitorJob::LambdaExprPartsKind: {
2434 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002435 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002436 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2437 CEnd = E->explicit_capture_end();
2438 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002439 // FIXME: Lambda init-captures.
2440 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002441 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002442
Guy Benyei11169dd2012-12-18 14:30:41 +00002443 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2444 C->getLocation(),
2445 TU)))
2446 return true;
2447 }
2448
2449 // Visit parameters and return type, if present.
2450 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2451 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2452 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2453 // Visit the whole type.
2454 if (Visit(TL))
2455 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002456 } else if (FunctionProtoTypeLoc Proto =
2457 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002458 if (E->hasExplicitParameters()) {
2459 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002460 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2461 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002462 return true;
2463 } else {
2464 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002465 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002466 return true;
2467 }
2468 }
2469 }
2470 break;
2471 }
2472
2473 case VisitorJob::PostChildrenVisitKind:
2474 if (PostChildrenVisitor(Parent, ClientData))
2475 return true;
2476 break;
2477 }
2478 }
2479 return false;
2480}
2481
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002482bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002483 VisitorWorkList *WL = 0;
2484 if (!WorkListFreeList.empty()) {
2485 WL = WorkListFreeList.back();
2486 WL->clear();
2487 WorkListFreeList.pop_back();
2488 }
2489 else {
2490 WL = new VisitorWorkList();
2491 WorkListCache.push_back(WL);
2492 }
2493 EnqueueWorkList(*WL, S);
2494 bool result = RunVisitorWorkList(*WL);
2495 WorkListFreeList.push_back(WL);
2496 return result;
2497}
2498
2499namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002500typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002501RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2502 const DeclarationNameInfo &NI,
2503 const SourceRange &QLoc,
2504 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2505 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2506 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2507 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2508
2509 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2510
2511 RefNamePieces Pieces;
2512
2513 if (WantQualifier && QLoc.isValid())
2514 Pieces.push_back(QLoc);
2515
2516 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2517 Pieces.push_back(NI.getLoc());
2518
2519 if (WantTemplateArgs && TemplateArgs)
2520 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2521 TemplateArgs->RAngleLoc));
2522
2523 if (Kind == DeclarationName::CXXOperatorName) {
2524 Pieces.push_back(SourceLocation::getFromRawEncoding(
2525 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2526 Pieces.push_back(SourceLocation::getFromRawEncoding(
2527 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2528 }
2529
2530 if (WantSinglePiece) {
2531 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2532 Pieces.clear();
2533 Pieces.push_back(R);
2534 }
2535
2536 return Pieces;
2537}
2538}
2539
2540//===----------------------------------------------------------------------===//
2541// Misc. API hooks.
2542//===----------------------------------------------------------------------===//
2543
2544static llvm::sys::Mutex EnableMultithreadingMutex;
2545static bool EnabledMultithreading;
2546
Chad Rosier05c71aa2013-03-27 18:28:23 +00002547static void fatal_error_handler(void *user_data, const std::string& reason,
2548 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002549 // Write the result out to stderr avoiding errs() because raw_ostreams can
2550 // call report_fatal_error.
2551 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2552 ::abort();
2553}
2554
2555extern "C" {
2556CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2557 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002558 // We use crash recovery to make some of our APIs more reliable, implicitly
2559 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002560 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2561 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002562
2563 // Enable support for multithreading in LLVM.
2564 {
2565 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2566 if (!EnabledMultithreading) {
2567 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2568 llvm::llvm_start_multithreaded();
2569 EnabledMultithreading = true;
2570 }
2571 }
2572
2573 CIndexer *CIdxr = new CIndexer();
2574 if (excludeDeclarationsFromPCH)
2575 CIdxr->setOnlyLocalDecls();
2576 if (displayDiagnostics)
2577 CIdxr->setDisplayDiagnostics();
2578
2579 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2580 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2581 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2582 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2583 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2584 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2585
2586 return CIdxr;
2587}
2588
2589void clang_disposeIndex(CXIndex CIdx) {
2590 if (CIdx)
2591 delete static_cast<CIndexer *>(CIdx);
2592}
2593
2594void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2595 if (CIdx)
2596 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2597}
2598
2599unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2600 if (CIdx)
2601 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2602 return 0;
2603}
2604
2605void clang_toggleCrashRecovery(unsigned isEnabled) {
2606 if (isEnabled)
2607 llvm::CrashRecoveryContext::Enable();
2608 else
2609 llvm::CrashRecoveryContext::Disable();
2610}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002611
Guy Benyei11169dd2012-12-18 14:30:41 +00002612CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2613 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002614 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002615 enum CXErrorCode Result =
2616 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002617 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002618 assert((TU && Result == CXError_Success) ||
2619 (!TU && Result != CXError_Success));
2620 return TU;
2621}
2622
2623enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2624 const char *ast_filename,
2625 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002626 if (out_TU)
2627 *out_TU = NULL;
2628
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002629 if (!CIdx || !ast_filename || !out_TU)
2630 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002631
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002632 LOG_FUNC_SECTION {
2633 *Log << ast_filename;
2634 }
2635
Guy Benyei11169dd2012-12-18 14:30:41 +00002636 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2637 FileSystemOptions FileSystemOpts;
2638
2639 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002640 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002641 CXXIdx->getOnlyLocalDecls(), None,
2642 /*CaptureDiagnostics=*/true,
2643 /*AllowPCHWithCompilerErrors=*/true,
2644 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002645 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2646 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002647}
2648
2649unsigned clang_defaultEditingTranslationUnitOptions() {
2650 return CXTranslationUnit_PrecompiledPreamble |
2651 CXTranslationUnit_CacheCompletionResults;
2652}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002653
Guy Benyei11169dd2012-12-18 14:30:41 +00002654CXTranslationUnit
2655clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2656 const char *source_filename,
2657 int num_command_line_args,
2658 const char * const *command_line_args,
2659 unsigned num_unsaved_files,
2660 struct CXUnsavedFile *unsaved_files) {
2661 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2662 return clang_parseTranslationUnit(CIdx, source_filename,
2663 command_line_args, num_command_line_args,
2664 unsaved_files, num_unsaved_files,
2665 Options);
2666}
2667
2668struct ParseTranslationUnitInfo {
2669 CXIndex CIdx;
2670 const char *source_filename;
2671 const char *const *command_line_args;
2672 int num_command_line_args;
2673 struct CXUnsavedFile *unsaved_files;
2674 unsigned num_unsaved_files;
2675 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002676 CXTranslationUnit *out_TU;
2677 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002678};
2679static void clang_parseTranslationUnit_Impl(void *UserData) {
2680 ParseTranslationUnitInfo *PTUI =
2681 static_cast<ParseTranslationUnitInfo*>(UserData);
2682 CXIndex CIdx = PTUI->CIdx;
2683 const char *source_filename = PTUI->source_filename;
2684 const char * const *command_line_args = PTUI->command_line_args;
2685 int num_command_line_args = PTUI->num_command_line_args;
2686 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2687 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2688 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002689 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002690
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002691 // Set up the initial return values.
2692 if (out_TU)
2693 *out_TU = NULL;
2694 PTUI->result = CXError_Failure;
2695
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002696 // Check arguments.
2697 if (!CIdx || !out_TU ||
2698 (unsaved_files == NULL && num_unsaved_files != 0)) {
2699 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002700 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002701 }
2702
Guy Benyei11169dd2012-12-18 14:30:41 +00002703 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2704
2705 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2706 setThreadBackgroundPriority();
2707
2708 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2709 // FIXME: Add a flag for modules.
2710 TranslationUnitKind TUKind
2711 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002712 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002713 = options & CXTranslationUnit_CacheCompletionResults;
2714 bool IncludeBriefCommentsInCodeCompletion
2715 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2716 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2717 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2718
2719 // Configure the diagnostics.
2720 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002721 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002722
2723 // Recover resources if we crash before exiting this function.
2724 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2725 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2726 DiagCleanup(Diags.getPtr());
2727
2728 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2729 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2730
2731 // Recover resources if we crash before exiting this function.
2732 llvm::CrashRecoveryContextCleanupRegistrar<
2733 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2734
2735 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2736 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2737 const llvm::MemoryBuffer *Buffer
2738 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2739 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2740 Buffer));
2741 }
2742
2743 OwningPtr<std::vector<const char *> >
2744 Args(new std::vector<const char*>());
2745
2746 // Recover resources if we crash before exiting this method.
2747 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2748 ArgsCleanup(Args.get());
2749
2750 // Since the Clang C library is primarily used by batch tools dealing with
2751 // (often very broken) source code, where spell-checking can have a
2752 // significant negative impact on performance (particularly when
2753 // precompiled headers are involved), we disable it by default.
2754 // Only do this if we haven't found a spell-checking-related argument.
2755 bool FoundSpellCheckingArgument = false;
2756 for (int I = 0; I != num_command_line_args; ++I) {
2757 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2758 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2759 FoundSpellCheckingArgument = true;
2760 break;
2761 }
2762 }
2763 if (!FoundSpellCheckingArgument)
2764 Args->push_back("-fno-spell-checking");
2765
2766 Args->insert(Args->end(), command_line_args,
2767 command_line_args + num_command_line_args);
2768
2769 // The 'source_filename' argument is optional. If the caller does not
2770 // specify it then it is assumed that the source file is specified
2771 // in the actual argument list.
2772 // Put the source file after command_line_args otherwise if '-x' flag is
2773 // present it will be unused.
2774 if (source_filename)
2775 Args->push_back(source_filename);
2776
2777 // Do we need the detailed preprocessing record?
2778 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2779 Args->push_back("-Xclang");
2780 Args->push_back("-detailed-preprocessing-record");
2781 }
2782
2783 unsigned NumErrors = Diags->getClient()->getNumErrors();
2784 OwningPtr<ASTUnit> ErrUnit;
2785 OwningPtr<ASTUnit> Unit(
2786 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2787 /* vector::data() not portable */,
2788 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2789 Diags,
2790 CXXIdx->getClangResourcesPath(),
2791 CXXIdx->getOnlyLocalDecls(),
2792 /*CaptureDiagnostics=*/true,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002793 *RemappedFiles.get(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002794 /*RemappedFilesKeepOriginalName=*/true,
2795 PrecompilePreamble,
2796 TUKind,
Alp Toker8c8a8752013-12-03 06:53:35 +00002797 CacheCodeCompletionResults,
Guy Benyei11169dd2012-12-18 14:30:41 +00002798 IncludeBriefCommentsInCodeCompletion,
2799 /*AllowPCHWithCompilerErrors=*/true,
2800 SkipFunctionBodies,
2801 /*UserFilesAreVolatile=*/true,
2802 ForSerialization,
2803 &ErrUnit));
2804
2805 if (NumErrors != Diags->getClient()->getNumErrors()) {
2806 // Make sure to check that 'Unit' is non-NULL.
2807 if (CXXIdx->getDisplayDiagnostics())
2808 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2809 }
2810
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002811 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2812 PTUI->result = CXError_ASTReadError;
2813 } else {
2814 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.take());
2815 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2816 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002817}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002818
2819CXTranslationUnit
2820clang_parseTranslationUnit(CXIndex CIdx,
2821 const char *source_filename,
2822 const char *const *command_line_args,
2823 int num_command_line_args,
2824 struct CXUnsavedFile *unsaved_files,
2825 unsigned num_unsaved_files,
2826 unsigned options) {
2827 CXTranslationUnit TU;
2828 enum CXErrorCode Result = clang_parseTranslationUnit2(
2829 CIdx, source_filename, command_line_args, num_command_line_args,
2830 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002831 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002832 assert((TU && Result == CXError_Success) ||
2833 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002834 return TU;
2835}
2836
2837enum CXErrorCode clang_parseTranslationUnit2(
2838 CXIndex CIdx,
2839 const char *source_filename,
2840 const char *const *command_line_args,
2841 int num_command_line_args,
2842 struct CXUnsavedFile *unsaved_files,
2843 unsigned num_unsaved_files,
2844 unsigned options,
2845 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002846 LOG_FUNC_SECTION {
2847 *Log << source_filename << ": ";
2848 for (int i = 0; i != num_command_line_args; ++i)
2849 *Log << command_line_args[i] << " ";
2850 }
2851
Guy Benyei11169dd2012-12-18 14:30:41 +00002852 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2853 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002854 num_unsaved_files, options, out_TU,
2855 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002856 llvm::CrashRecoveryContext CRC;
2857
2858 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2859 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2860 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2861 fprintf(stderr, " 'command_line_args' : [");
2862 for (int i = 0; i != num_command_line_args; ++i) {
2863 if (i)
2864 fprintf(stderr, ", ");
2865 fprintf(stderr, "'%s'", command_line_args[i]);
2866 }
2867 fprintf(stderr, "],\n");
2868 fprintf(stderr, " 'unsaved_files' : [");
2869 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2870 if (i)
2871 fprintf(stderr, ", ");
2872 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2873 unsaved_files[i].Length);
2874 }
2875 fprintf(stderr, "],\n");
2876 fprintf(stderr, " 'options' : %d,\n", options);
2877 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002878
2879 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002880 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002881 if (CXTranslationUnit *TU = PTUI.out_TU)
2882 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002883 }
2884
2885 return PTUI.result;
2886}
2887
2888unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2889 return CXSaveTranslationUnit_None;
2890}
2891
2892namespace {
2893
2894struct SaveTranslationUnitInfo {
2895 CXTranslationUnit TU;
2896 const char *FileName;
2897 unsigned options;
2898 CXSaveError result;
2899};
2900
2901}
2902
2903static void clang_saveTranslationUnit_Impl(void *UserData) {
2904 SaveTranslationUnitInfo *STUI =
2905 static_cast<SaveTranslationUnitInfo*>(UserData);
2906
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002907 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002908 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2909 setThreadBackgroundPriority();
2910
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002911 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002912 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2913}
2914
2915int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2916 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002917 LOG_FUNC_SECTION {
2918 *Log << TU << ' ' << FileName;
2919 }
2920
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002921 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002922 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002923 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002924 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002925
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002926 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002927 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2928 if (!CXXUnit->hasSema())
2929 return CXSaveError_InvalidTU;
2930
2931 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2932
2933 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2934 getenv("LIBCLANG_NOTHREADS")) {
2935 clang_saveTranslationUnit_Impl(&STUI);
2936
2937 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2938 PrintLibclangResourceUsage(TU);
2939
2940 return STUI.result;
2941 }
2942
2943 // We have an AST that has invalid nodes due to compiler errors.
2944 // Use a crash recovery thread for protection.
2945
2946 llvm::CrashRecoveryContext CRC;
2947
2948 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2949 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2950 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2951 fprintf(stderr, " 'options' : %d,\n", options);
2952 fprintf(stderr, "}\n");
2953
2954 return CXSaveError_Unknown;
2955
2956 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2957 PrintLibclangResourceUsage(TU);
2958 }
2959
2960 return STUI.result;
2961}
2962
2963void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2964 if (CTUnit) {
2965 // If the translation unit has been marked as unsafe to free, just discard
2966 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002967 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2968 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002969 return;
2970
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002971 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002972 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002973 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2974 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002975 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002976 delete CTUnit;
2977 }
2978}
2979
2980unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2981 return CXReparse_None;
2982}
2983
2984struct ReparseTranslationUnitInfo {
2985 CXTranslationUnit TU;
2986 unsigned num_unsaved_files;
2987 struct CXUnsavedFile *unsaved_files;
2988 unsigned options;
2989 int result;
2990};
2991
2992static void clang_reparseTranslationUnit_Impl(void *UserData) {
2993 ReparseTranslationUnitInfo *RTUI =
2994 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002995 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002996
Guy Benyei11169dd2012-12-18 14:30:41 +00002997 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002998 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2999 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
3000 unsigned options = RTUI->options;
3001 (void) options;
3002
3003 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003004 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003005 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003006 RTUI->result = CXError_InvalidArguments;
3007 return;
3008 }
3009 if (unsaved_files == NULL && num_unsaved_files != 0) {
3010 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003011 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003012 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003013
3014 // Reset the associated diagnostics.
3015 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3016 TU->Diagnostics = 0;
3017
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003018 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003019 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3020 setThreadBackgroundPriority();
3021
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003022 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003023 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3024
3025 OwningPtr<std::vector<ASTUnit::RemappedFile> >
3026 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
3027
3028 // Recover resources if we crash before exiting this function.
3029 llvm::CrashRecoveryContextCleanupRegistrar<
3030 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3031
3032 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3033 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3034 const llvm::MemoryBuffer *Buffer
3035 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3036 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3037 Buffer));
3038 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003039
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003040 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003041 RTUI->result = CXError_Success;
3042 else if (isASTReadError(CXXUnit))
3043 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003044}
3045
3046int clang_reparseTranslationUnit(CXTranslationUnit TU,
3047 unsigned num_unsaved_files,
3048 struct CXUnsavedFile *unsaved_files,
3049 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003050 LOG_FUNC_SECTION {
3051 *Log << TU;
3052 }
3053
Guy Benyei11169dd2012-12-18 14:30:41 +00003054 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003055 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003056
3057 if (getenv("LIBCLANG_NOTHREADS")) {
3058 clang_reparseTranslationUnit_Impl(&RTUI);
3059 return RTUI.result;
3060 }
3061
3062 llvm::CrashRecoveryContext CRC;
3063
3064 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3065 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003066 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003067 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003068 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3069 PrintLibclangResourceUsage(TU);
3070
3071 return RTUI.result;
3072}
3073
3074
3075CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003076 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003077 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003078 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003079 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003080
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003081 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003082 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003083}
3084
3085CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003086 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003087 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003088 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003089 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003090
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003091 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003092 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3093}
3094
3095} // end: extern "C"
3096
3097//===----------------------------------------------------------------------===//
3098// CXFile Operations.
3099//===----------------------------------------------------------------------===//
3100
3101extern "C" {
3102CXString clang_getFileName(CXFile SFile) {
3103 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003104 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003105
3106 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003107 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003108}
3109
3110time_t clang_getFileTime(CXFile SFile) {
3111 if (!SFile)
3112 return 0;
3113
3114 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3115 return FEnt->getModificationTime();
3116}
3117
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003118CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003119 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003120 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003121 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003122 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003123
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003124 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003125
3126 FileManager &FMgr = CXXUnit->getFileManager();
3127 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3128}
3129
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003130unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3131 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003132 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003133 LOG_BAD_TU(TU);
3134 return 0;
3135 }
3136
3137 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003138 return 0;
3139
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003140 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003141 FileEntry *FEnt = static_cast<FileEntry *>(file);
3142 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3143 .isFileMultipleIncludeGuarded(FEnt);
3144}
3145
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003146int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3147 if (!file || !outID)
3148 return 1;
3149
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003150 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003151 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3152 outID->data[0] = ID.getDevice();
3153 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003154 outID->data[2] = FEnt->getModificationTime();
3155 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003156}
3157
Guy Benyei11169dd2012-12-18 14:30:41 +00003158} // end: extern "C"
3159
3160//===----------------------------------------------------------------------===//
3161// CXCursor Operations.
3162//===----------------------------------------------------------------------===//
3163
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003164static const Decl *getDeclFromExpr(const Stmt *E) {
3165 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003166 return getDeclFromExpr(CE->getSubExpr());
3167
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003168 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003169 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003170 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003171 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003172 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003173 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003174 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003175 if (PRE->isExplicitProperty())
3176 return PRE->getExplicitProperty();
3177 // It could be messaging both getter and setter as in:
3178 // ++myobj.myprop;
3179 // in which case prefer to associate the setter since it is less obvious
3180 // from inspecting the source that the setter is going to get called.
3181 if (PRE->isMessagingSetter())
3182 return PRE->getImplicitPropertySetter();
3183 return PRE->getImplicitPropertyGetter();
3184 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003185 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003186 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003187 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003188 if (Expr *Src = OVE->getSourceExpr())
3189 return getDeclFromExpr(Src);
3190
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003191 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003192 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003193 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003194 if (!CE->isElidable())
3195 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003196 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003197 return OME->getMethodDecl();
3198
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003199 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003200 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003201 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003202 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3203 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003204 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003205 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3206 isa<ParmVarDecl>(SizeOfPack->getPack()))
3207 return SizeOfPack->getPack();
3208
3209 return 0;
3210}
3211
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003212static SourceLocation getLocationFromExpr(const Expr *E) {
3213 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003214 return getLocationFromExpr(CE->getSubExpr());
3215
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003216 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003217 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003218 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003219 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003220 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003221 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003222 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003223 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003224 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003225 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003226 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003227 return PropRef->getLocation();
3228
3229 return E->getLocStart();
3230}
3231
3232extern "C" {
3233
3234unsigned clang_visitChildren(CXCursor parent,
3235 CXCursorVisitor visitor,
3236 CXClientData client_data) {
3237 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3238 /*VisitPreprocessorLast=*/false);
3239 return CursorVis.VisitChildren(parent);
3240}
3241
3242#ifndef __has_feature
3243#define __has_feature(x) 0
3244#endif
3245#if __has_feature(blocks)
3246typedef enum CXChildVisitResult
3247 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3248
3249static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3250 CXClientData client_data) {
3251 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3252 return block(cursor, parent);
3253}
3254#else
3255// If we are compiled with a compiler that doesn't have native blocks support,
3256// define and call the block manually, so the
3257typedef struct _CXChildVisitResult
3258{
3259 void *isa;
3260 int flags;
3261 int reserved;
3262 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3263 CXCursor);
3264} *CXCursorVisitorBlock;
3265
3266static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3267 CXClientData client_data) {
3268 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3269 return block->invoke(block, cursor, parent);
3270}
3271#endif
3272
3273
3274unsigned clang_visitChildrenWithBlock(CXCursor parent,
3275 CXCursorVisitorBlock block) {
3276 return clang_visitChildren(parent, visitWithBlock, block);
3277}
3278
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003279static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003280 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003281 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003282
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003283 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003284 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003285 if (const ObjCPropertyImplDecl *PropImpl =
3286 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003287 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003288 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003289
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003290 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003291 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003292 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003293
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003294 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003295 }
3296
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003297 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003298 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003299
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003300 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003301 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3302 // and returns different names. NamedDecl returns the class name and
3303 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003304 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003305
3306 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003307 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003308
3309 SmallString<1024> S;
3310 llvm::raw_svector_ostream os(S);
3311 ND->printName(os);
3312
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003313 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003314}
3315
3316CXString clang_getCursorSpelling(CXCursor C) {
3317 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003318 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003319
3320 if (clang_isReference(C.kind)) {
3321 switch (C.kind) {
3322 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003323 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003324 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003325 }
3326 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003327 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003328 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003329 }
3330 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003331 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003332 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003333 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 }
3335 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003336 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003337 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 }
3339 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003340 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003341 assert(Type && "Missing type decl");
3342
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003343 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003344 getAsString());
3345 }
3346 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003347 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 assert(Template && "Missing template decl");
3349
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003350 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003351 }
3352
3353 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003354 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003355 assert(NS && "Missing namespace decl");
3356
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003357 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003358 }
3359
3360 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003361 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003362 assert(Field && "Missing member decl");
3363
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003364 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003365 }
3366
3367 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003368 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003369 assert(Label && "Missing label");
3370
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003371 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003372 }
3373
3374 case CXCursor_OverloadedDeclRef: {
3375 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003376 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3377 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003378 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003379 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003381 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003382 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003383 OverloadedTemplateStorage *Ovl
3384 = Storage.get<OverloadedTemplateStorage*>();
3385 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003386 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003387 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003388 }
3389
3390 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003391 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003392 assert(Var && "Missing variable decl");
3393
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003394 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003395 }
3396
3397 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003398 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003399 }
3400 }
3401
3402 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003403 const Expr *E = getCursorExpr(C);
3404
3405 if (C.kind == CXCursor_ObjCStringLiteral ||
3406 C.kind == CXCursor_StringLiteral) {
3407 const StringLiteral *SLit;
3408 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3409 SLit = OSL->getString();
3410 } else {
3411 SLit = cast<StringLiteral>(E);
3412 }
3413 SmallString<256> Buf;
3414 llvm::raw_svector_ostream OS(Buf);
3415 SLit->outputString(OS);
3416 return cxstring::createDup(OS.str());
3417 }
3418
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003419 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003420 if (D)
3421 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003422 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003423 }
3424
3425 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003426 const Stmt *S = getCursorStmt(C);
3427 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003428 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003429
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003430 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003431 }
3432
3433 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003434 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003435 ->getNameStart());
3436
3437 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003438 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003439 ->getNameStart());
3440
3441 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003442 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003443
3444 if (clang_isDeclaration(C.kind))
3445 return getDeclSpelling(getCursorDecl(C));
3446
3447 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003448 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003449 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003450 }
3451
3452 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003453 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003454 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003455 }
3456
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003457 if (C.kind == CXCursor_PackedAttr) {
3458 return cxstring::createRef("packed");
3459 }
3460
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003461 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003462}
3463
3464CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3465 unsigned pieceIndex,
3466 unsigned options) {
3467 if (clang_Cursor_isNull(C))
3468 return clang_getNullRange();
3469
3470 ASTContext &Ctx = getCursorContext(C);
3471
3472 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003473 const Stmt *S = getCursorStmt(C);
3474 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003475 if (pieceIndex > 0)
3476 return clang_getNullRange();
3477 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3478 }
3479
3480 return clang_getNullRange();
3481 }
3482
3483 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003484 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003485 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3486 if (pieceIndex >= ME->getNumSelectorLocs())
3487 return clang_getNullRange();
3488 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3489 }
3490 }
3491
3492 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3493 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003494 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003495 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3496 if (pieceIndex >= MD->getNumSelectorLocs())
3497 return clang_getNullRange();
3498 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3499 }
3500 }
3501
3502 if (C.kind == CXCursor_ObjCCategoryDecl ||
3503 C.kind == CXCursor_ObjCCategoryImplDecl) {
3504 if (pieceIndex > 0)
3505 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003506 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003507 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3508 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003509 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003510 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3511 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3512 }
3513
3514 if (C.kind == CXCursor_ModuleImportDecl) {
3515 if (pieceIndex > 0)
3516 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003517 if (const ImportDecl *ImportD =
3518 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003519 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3520 if (!Locs.empty())
3521 return cxloc::translateSourceRange(Ctx,
3522 SourceRange(Locs.front(), Locs.back()));
3523 }
3524 return clang_getNullRange();
3525 }
3526
3527 // FIXME: A CXCursor_InclusionDirective should give the location of the
3528 // filename, but we don't keep track of this.
3529
3530 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3531 // but we don't keep track of this.
3532
3533 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3534 // but we don't keep track of this.
3535
3536 // Default handling, give the location of the cursor.
3537
3538 if (pieceIndex > 0)
3539 return clang_getNullRange();
3540
3541 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3542 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3543 return cxloc::translateSourceRange(Ctx, Loc);
3544}
3545
3546CXString clang_getCursorDisplayName(CXCursor C) {
3547 if (!clang_isDeclaration(C.kind))
3548 return clang_getCursorSpelling(C);
3549
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003550 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003551 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003552 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003553
3554 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003555 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003556 D = FunTmpl->getTemplatedDecl();
3557
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003558 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003559 SmallString<64> Str;
3560 llvm::raw_svector_ostream OS(Str);
3561 OS << *Function;
3562 if (Function->getPrimaryTemplate())
3563 OS << "<>";
3564 OS << "(";
3565 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3566 if (I)
3567 OS << ", ";
3568 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3569 }
3570
3571 if (Function->isVariadic()) {
3572 if (Function->getNumParams())
3573 OS << ", ";
3574 OS << "...";
3575 }
3576 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003577 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003578 }
3579
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003580 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003581 SmallString<64> Str;
3582 llvm::raw_svector_ostream OS(Str);
3583 OS << *ClassTemplate;
3584 OS << "<";
3585 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3586 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3587 if (I)
3588 OS << ", ";
3589
3590 NamedDecl *Param = Params->getParam(I);
3591 if (Param->getIdentifier()) {
3592 OS << Param->getIdentifier()->getName();
3593 continue;
3594 }
3595
3596 // There is no parameter name, which makes this tricky. Try to come up
3597 // with something useful that isn't too long.
3598 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3599 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3600 else if (NonTypeTemplateParmDecl *NTTP
3601 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3602 OS << NTTP->getType().getAsString(Policy);
3603 else
3604 OS << "template<...> class";
3605 }
3606
3607 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003608 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003609 }
3610
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003611 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003612 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3613 // If the type was explicitly written, use that.
3614 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003615 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003616
Benjamin Kramer9170e912013-02-22 15:46:01 +00003617 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003618 llvm::raw_svector_ostream OS(Str);
3619 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003620 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003621 ClassSpec->getTemplateArgs().data(),
3622 ClassSpec->getTemplateArgs().size(),
3623 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003624 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 }
3626
3627 return clang_getCursorSpelling(C);
3628}
3629
3630CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3631 switch (Kind) {
3632 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003633 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003635 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003637 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003641 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003643 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003645 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003647 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003651 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003653 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003655 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003659 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003663 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003665 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003673 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003760 case CXCursor_ObjCSelfExpr:
3761 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003878 case CXCursor_PackedAttr:
3879 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003928 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003929 return cxstring::createRef("OMPParallelDirective");
3930 case CXCursor_OMPSimdDirective:
3931 return cxstring::createRef("OMPSimdDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 }
3933
3934 llvm_unreachable("Unhandled CXCursorKind");
3935}
3936
3937struct GetCursorData {
3938 SourceLocation TokenBeginLoc;
3939 bool PointsAtMacroArgExpansion;
3940 bool VisitedObjCPropertyImplDecl;
3941 SourceLocation VisitedDeclaratorDeclStartLoc;
3942 CXCursor &BestCursor;
3943
3944 GetCursorData(SourceManager &SM,
3945 SourceLocation tokenBegin, CXCursor &outputCursor)
3946 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3947 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3948 VisitedObjCPropertyImplDecl = false;
3949 }
3950};
3951
3952static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3953 CXCursor parent,
3954 CXClientData client_data) {
3955 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3956 CXCursor *BestCursor = &Data->BestCursor;
3957
3958 // If we point inside a macro argument we should provide info of what the
3959 // token is so use the actual cursor, don't replace it with a macro expansion
3960 // cursor.
3961 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3962 return CXChildVisit_Recurse;
3963
3964 if (clang_isDeclaration(cursor.kind)) {
3965 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003966 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3968 if (MD->isImplicit())
3969 return CXChildVisit_Break;
3970
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003971 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3973 // Check that when we have multiple @class references in the same line,
3974 // that later ones do not override the previous ones.
3975 // If we have:
3976 // @class Foo, Bar;
3977 // source ranges for both start at '@', so 'Bar' will end up overriding
3978 // 'Foo' even though the cursor location was at 'Foo'.
3979 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3980 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003981 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003982 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3983 if (PrevID != ID &&
3984 !PrevID->isThisDeclarationADefinition() &&
3985 !ID->isThisDeclarationADefinition())
3986 return CXChildVisit_Break;
3987 }
3988
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003989 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003990 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3991 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3992 // Check that when we have multiple declarators in the same line,
3993 // that later ones do not override the previous ones.
3994 // If we have:
3995 // int Foo, Bar;
3996 // source ranges for both start at 'int', so 'Bar' will end up overriding
3997 // 'Foo' even though the cursor location was at 'Foo'.
3998 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3999 return CXChildVisit_Break;
4000 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4001
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004002 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4004 (void)PropImp;
4005 // Check that when we have multiple @synthesize in the same line,
4006 // that later ones do not override the previous ones.
4007 // If we have:
4008 // @synthesize Foo, Bar;
4009 // source ranges for both start at '@', so 'Bar' will end up overriding
4010 // 'Foo' even though the cursor location was at 'Foo'.
4011 if (Data->VisitedObjCPropertyImplDecl)
4012 return CXChildVisit_Break;
4013 Data->VisitedObjCPropertyImplDecl = true;
4014 }
4015 }
4016
4017 if (clang_isExpression(cursor.kind) &&
4018 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004019 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004020 // Avoid having the cursor of an expression replace the declaration cursor
4021 // when the expression source range overlaps the declaration range.
4022 // This can happen for C++ constructor expressions whose range generally
4023 // include the variable declaration, e.g.:
4024 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4025 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4026 D->getLocation() == Data->TokenBeginLoc)
4027 return CXChildVisit_Break;
4028 }
4029 }
4030
4031 // If our current best cursor is the construction of a temporary object,
4032 // don't replace that cursor with a type reference, because we want
4033 // clang_getCursor() to point at the constructor.
4034 if (clang_isExpression(BestCursor->kind) &&
4035 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4036 cursor.kind == CXCursor_TypeRef) {
4037 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4038 // as having the actual point on the type reference.
4039 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4040 return CXChildVisit_Recurse;
4041 }
4042
4043 *BestCursor = cursor;
4044 return CXChildVisit_Recurse;
4045}
4046
4047CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004048 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004049 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004051 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004052
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004053 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004054 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4055
4056 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4057 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4058
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004059 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 CXFile SearchFile;
4061 unsigned SearchLine, SearchColumn;
4062 CXFile ResultFile;
4063 unsigned ResultLine, ResultColumn;
4064 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4065 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4066 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4067
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004068 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4069 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 &ResultColumn, 0);
4071 SearchFileName = clang_getFileName(SearchFile);
4072 ResultFileName = clang_getFileName(ResultFile);
4073 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4074 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004075 *Log << llvm::format("(%s:%d:%d) = %s",
4076 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4077 clang_getCString(KindSpelling))
4078 << llvm::format("(%s:%d:%d):%s%s",
4079 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4080 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004081 clang_disposeString(SearchFileName);
4082 clang_disposeString(ResultFileName);
4083 clang_disposeString(KindSpelling);
4084 clang_disposeString(USR);
4085
4086 CXCursor Definition = clang_getCursorDefinition(Result);
4087 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4088 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4089 CXString DefinitionKindSpelling
4090 = clang_getCursorKindSpelling(Definition.kind);
4091 CXFile DefinitionFile;
4092 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004093 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004094 &DefinitionLine, &DefinitionColumn, 0);
4095 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004096 *Log << llvm::format(" -> %s(%s:%d:%d)",
4097 clang_getCString(DefinitionKindSpelling),
4098 clang_getCString(DefinitionFileName),
4099 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004100 clang_disposeString(DefinitionFileName);
4101 clang_disposeString(DefinitionKindSpelling);
4102 }
4103 }
4104
4105 return Result;
4106}
4107
4108CXCursor clang_getNullCursor(void) {
4109 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4110}
4111
4112unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004113 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4114 // can't set consistently. For example, when visiting a DeclStmt we will set
4115 // it but we don't set it on the result of clang_getCursorDefinition for
4116 // a reference of the same declaration.
4117 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4118 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4119 // to provide that kind of info.
4120 if (clang_isDeclaration(X.kind))
4121 X.data[1] = 0;
4122 if (clang_isDeclaration(Y.kind))
4123 Y.data[1] = 0;
4124
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 return X == Y;
4126}
4127
4128unsigned clang_hashCursor(CXCursor C) {
4129 unsigned Index = 0;
4130 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4131 Index = 1;
4132
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004133 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004134 std::make_pair(C.kind, C.data[Index]));
4135}
4136
4137unsigned clang_isInvalid(enum CXCursorKind K) {
4138 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4139}
4140
4141unsigned clang_isDeclaration(enum CXCursorKind K) {
4142 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4143 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4144}
4145
4146unsigned clang_isReference(enum CXCursorKind K) {
4147 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4148}
4149
4150unsigned clang_isExpression(enum CXCursorKind K) {
4151 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4152}
4153
4154unsigned clang_isStatement(enum CXCursorKind K) {
4155 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4156}
4157
4158unsigned clang_isAttribute(enum CXCursorKind K) {
4159 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4160}
4161
4162unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4163 return K == CXCursor_TranslationUnit;
4164}
4165
4166unsigned clang_isPreprocessing(enum CXCursorKind K) {
4167 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4168}
4169
4170unsigned clang_isUnexposed(enum CXCursorKind K) {
4171 switch (K) {
4172 case CXCursor_UnexposedDecl:
4173 case CXCursor_UnexposedExpr:
4174 case CXCursor_UnexposedStmt:
4175 case CXCursor_UnexposedAttr:
4176 return true;
4177 default:
4178 return false;
4179 }
4180}
4181
4182CXCursorKind clang_getCursorKind(CXCursor C) {
4183 return C.kind;
4184}
4185
4186CXSourceLocation clang_getCursorLocation(CXCursor C) {
4187 if (clang_isReference(C.kind)) {
4188 switch (C.kind) {
4189 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004190 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004191 = getCursorObjCSuperClassRef(C);
4192 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4193 }
4194
4195 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004196 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004197 = getCursorObjCProtocolRef(C);
4198 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4199 }
4200
4201 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004202 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 = getCursorObjCClassRef(C);
4204 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4205 }
4206
4207 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004208 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004209 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4210 }
4211
4212 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004213 std::pair<const TemplateDecl *, SourceLocation> P =
4214 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4216 }
4217
4218 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004219 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004220 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4221 }
4222
4223 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004224 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004225 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4226 }
4227
4228 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004229 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004230 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4231 }
4232
4233 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004234 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004235 if (!BaseSpec)
4236 return clang_getNullLocation();
4237
4238 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4239 return cxloc::translateSourceLocation(getCursorContext(C),
4240 TSInfo->getTypeLoc().getBeginLoc());
4241
4242 return cxloc::translateSourceLocation(getCursorContext(C),
4243 BaseSpec->getLocStart());
4244 }
4245
4246 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004247 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004248 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4249 }
4250
4251 case CXCursor_OverloadedDeclRef:
4252 return cxloc::translateSourceLocation(getCursorContext(C),
4253 getCursorOverloadedDeclRef(C).second);
4254
4255 default:
4256 // FIXME: Need a way to enumerate all non-reference cases.
4257 llvm_unreachable("Missed a reference kind");
4258 }
4259 }
4260
4261 if (clang_isExpression(C.kind))
4262 return cxloc::translateSourceLocation(getCursorContext(C),
4263 getLocationFromExpr(getCursorExpr(C)));
4264
4265 if (clang_isStatement(C.kind))
4266 return cxloc::translateSourceLocation(getCursorContext(C),
4267 getCursorStmt(C)->getLocStart());
4268
4269 if (C.kind == CXCursor_PreprocessingDirective) {
4270 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4271 return cxloc::translateSourceLocation(getCursorContext(C), L);
4272 }
4273
4274 if (C.kind == CXCursor_MacroExpansion) {
4275 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004276 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004277 return cxloc::translateSourceLocation(getCursorContext(C), L);
4278 }
4279
4280 if (C.kind == CXCursor_MacroDefinition) {
4281 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4282 return cxloc::translateSourceLocation(getCursorContext(C), L);
4283 }
4284
4285 if (C.kind == CXCursor_InclusionDirective) {
4286 SourceLocation L
4287 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4288 return cxloc::translateSourceLocation(getCursorContext(C), L);
4289 }
4290
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004291 if (clang_isAttribute(C.kind)) {
4292 SourceLocation L
4293 = cxcursor::getCursorAttr(C)->getLocation();
4294 return cxloc::translateSourceLocation(getCursorContext(C), L);
4295 }
4296
Guy Benyei11169dd2012-12-18 14:30:41 +00004297 if (!clang_isDeclaration(C.kind))
4298 return clang_getNullLocation();
4299
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004300 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004301 if (!D)
4302 return clang_getNullLocation();
4303
4304 SourceLocation Loc = D->getLocation();
4305 // FIXME: Multiple variables declared in a single declaration
4306 // currently lack the information needed to correctly determine their
4307 // ranges when accounting for the type-specifier. We use context
4308 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4309 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004310 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004311 if (!cxcursor::isFirstInDeclGroup(C))
4312 Loc = VD->getLocation();
4313 }
4314
4315 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004316 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004317 Loc = MD->getSelectorStartLoc();
4318
4319 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4320}
4321
4322} // end extern "C"
4323
4324CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4325 assert(TU);
4326
4327 // Guard against an invalid SourceLocation, or we may assert in one
4328 // of the following calls.
4329 if (SLoc.isInvalid())
4330 return clang_getNullCursor();
4331
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004332 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004333
4334 // Translate the given source location to make it point at the beginning of
4335 // the token under the cursor.
4336 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4337 CXXUnit->getASTContext().getLangOpts());
4338
4339 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4340 if (SLoc.isValid()) {
4341 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4342 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4343 /*VisitPreprocessorLast=*/true,
4344 /*VisitIncludedEntities=*/false,
4345 SourceLocation(SLoc));
4346 CursorVis.visitFileRegion();
4347 }
4348
4349 return Result;
4350}
4351
4352static SourceRange getRawCursorExtent(CXCursor C) {
4353 if (clang_isReference(C.kind)) {
4354 switch (C.kind) {
4355 case CXCursor_ObjCSuperClassRef:
4356 return getCursorObjCSuperClassRef(C).second;
4357
4358 case CXCursor_ObjCProtocolRef:
4359 return getCursorObjCProtocolRef(C).second;
4360
4361 case CXCursor_ObjCClassRef:
4362 return getCursorObjCClassRef(C).second;
4363
4364 case CXCursor_TypeRef:
4365 return getCursorTypeRef(C).second;
4366
4367 case CXCursor_TemplateRef:
4368 return getCursorTemplateRef(C).second;
4369
4370 case CXCursor_NamespaceRef:
4371 return getCursorNamespaceRef(C).second;
4372
4373 case CXCursor_MemberRef:
4374 return getCursorMemberRef(C).second;
4375
4376 case CXCursor_CXXBaseSpecifier:
4377 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4378
4379 case CXCursor_LabelRef:
4380 return getCursorLabelRef(C).second;
4381
4382 case CXCursor_OverloadedDeclRef:
4383 return getCursorOverloadedDeclRef(C).second;
4384
4385 case CXCursor_VariableRef:
4386 return getCursorVariableRef(C).second;
4387
4388 default:
4389 // FIXME: Need a way to enumerate all non-reference cases.
4390 llvm_unreachable("Missed a reference kind");
4391 }
4392 }
4393
4394 if (clang_isExpression(C.kind))
4395 return getCursorExpr(C)->getSourceRange();
4396
4397 if (clang_isStatement(C.kind))
4398 return getCursorStmt(C)->getSourceRange();
4399
4400 if (clang_isAttribute(C.kind))
4401 return getCursorAttr(C)->getRange();
4402
4403 if (C.kind == CXCursor_PreprocessingDirective)
4404 return cxcursor::getCursorPreprocessingDirective(C);
4405
4406 if (C.kind == CXCursor_MacroExpansion) {
4407 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004408 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004409 return TU->mapRangeFromPreamble(Range);
4410 }
4411
4412 if (C.kind == CXCursor_MacroDefinition) {
4413 ASTUnit *TU = getCursorASTUnit(C);
4414 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4415 return TU->mapRangeFromPreamble(Range);
4416 }
4417
4418 if (C.kind == CXCursor_InclusionDirective) {
4419 ASTUnit *TU = getCursorASTUnit(C);
4420 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4421 return TU->mapRangeFromPreamble(Range);
4422 }
4423
4424 if (C.kind == CXCursor_TranslationUnit) {
4425 ASTUnit *TU = getCursorASTUnit(C);
4426 FileID MainID = TU->getSourceManager().getMainFileID();
4427 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4428 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4429 return SourceRange(Start, End);
4430 }
4431
4432 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004433 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004434 if (!D)
4435 return SourceRange();
4436
4437 SourceRange R = D->getSourceRange();
4438 // FIXME: Multiple variables declared in a single declaration
4439 // currently lack the information needed to correctly determine their
4440 // ranges when accounting for the type-specifier. We use context
4441 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4442 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004443 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004444 if (!cxcursor::isFirstInDeclGroup(C))
4445 R.setBegin(VD->getLocation());
4446 }
4447 return R;
4448 }
4449 return SourceRange();
4450}
4451
4452/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4453/// the decl-specifier-seq for declarations.
4454static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4455 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004456 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004457 if (!D)
4458 return SourceRange();
4459
4460 SourceRange R = D->getSourceRange();
4461
4462 // Adjust the start of the location for declarations preceded by
4463 // declaration specifiers.
4464 SourceLocation StartLoc;
4465 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4466 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4467 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004468 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004469 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4470 StartLoc = TI->getTypeLoc().getLocStart();
4471 }
4472
4473 if (StartLoc.isValid() && R.getBegin().isValid() &&
4474 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4475 R.setBegin(StartLoc);
4476
4477 // FIXME: Multiple variables declared in a single declaration
4478 // currently lack the information needed to correctly determine their
4479 // ranges when accounting for the type-specifier. We use context
4480 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4481 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004482 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004483 if (!cxcursor::isFirstInDeclGroup(C))
4484 R.setBegin(VD->getLocation());
4485 }
4486
4487 return R;
4488 }
4489
4490 return getRawCursorExtent(C);
4491}
4492
4493extern "C" {
4494
4495CXSourceRange clang_getCursorExtent(CXCursor C) {
4496 SourceRange R = getRawCursorExtent(C);
4497 if (R.isInvalid())
4498 return clang_getNullRange();
4499
4500 return cxloc::translateSourceRange(getCursorContext(C), R);
4501}
4502
4503CXCursor clang_getCursorReferenced(CXCursor C) {
4504 if (clang_isInvalid(C.kind))
4505 return clang_getNullCursor();
4506
4507 CXTranslationUnit tu = getCursorTU(C);
4508 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004509 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004510 if (!D)
4511 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004512 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004513 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004514 if (const ObjCPropertyImplDecl *PropImpl =
4515 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004516 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4517 return MakeCXCursor(Property, tu);
4518
4519 return C;
4520 }
4521
4522 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004523 const Expr *E = getCursorExpr(C);
4524 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004525 if (D) {
4526 CXCursor declCursor = MakeCXCursor(D, tu);
4527 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4528 declCursor);
4529 return declCursor;
4530 }
4531
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004532 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004533 return MakeCursorOverloadedDeclRef(Ovl, tu);
4534
4535 return clang_getNullCursor();
4536 }
4537
4538 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004539 const Stmt *S = getCursorStmt(C);
4540 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004541 if (LabelDecl *label = Goto->getLabel())
4542 if (LabelStmt *labelS = label->getStmt())
4543 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4544
4545 return clang_getNullCursor();
4546 }
4547
4548 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004549 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004550 return MakeMacroDefinitionCursor(Def, tu);
4551 }
4552
4553 if (!clang_isReference(C.kind))
4554 return clang_getNullCursor();
4555
4556 switch (C.kind) {
4557 case CXCursor_ObjCSuperClassRef:
4558 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4559
4560 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004561 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4562 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004563 return MakeCXCursor(Def, tu);
4564
4565 return MakeCXCursor(Prot, tu);
4566 }
4567
4568 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004569 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4570 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004571 return MakeCXCursor(Def, tu);
4572
4573 return MakeCXCursor(Class, tu);
4574 }
4575
4576 case CXCursor_TypeRef:
4577 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4578
4579 case CXCursor_TemplateRef:
4580 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4581
4582 case CXCursor_NamespaceRef:
4583 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4584
4585 case CXCursor_MemberRef:
4586 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4587
4588 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004589 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004590 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4591 tu ));
4592 }
4593
4594 case CXCursor_LabelRef:
4595 // FIXME: We end up faking the "parent" declaration here because we
4596 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004597 return MakeCXCursor(getCursorLabelRef(C).first,
4598 cxtu::getASTUnit(tu)->getASTContext()
4599 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004600 tu);
4601
4602 case CXCursor_OverloadedDeclRef:
4603 return C;
4604
4605 case CXCursor_VariableRef:
4606 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4607
4608 default:
4609 // We would prefer to enumerate all non-reference cursor kinds here.
4610 llvm_unreachable("Unhandled reference cursor kind");
4611 }
4612}
4613
4614CXCursor clang_getCursorDefinition(CXCursor C) {
4615 if (clang_isInvalid(C.kind))
4616 return clang_getNullCursor();
4617
4618 CXTranslationUnit TU = getCursorTU(C);
4619
4620 bool WasReference = false;
4621 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4622 C = clang_getCursorReferenced(C);
4623 WasReference = true;
4624 }
4625
4626 if (C.kind == CXCursor_MacroExpansion)
4627 return clang_getCursorReferenced(C);
4628
4629 if (!clang_isDeclaration(C.kind))
4630 return clang_getNullCursor();
4631
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004632 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 if (!D)
4634 return clang_getNullCursor();
4635
4636 switch (D->getKind()) {
4637 // Declaration kinds that don't really separate the notions of
4638 // declaration and definition.
4639 case Decl::Namespace:
4640 case Decl::Typedef:
4641 case Decl::TypeAlias:
4642 case Decl::TypeAliasTemplate:
4643 case Decl::TemplateTypeParm:
4644 case Decl::EnumConstant:
4645 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004646 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004647 case Decl::IndirectField:
4648 case Decl::ObjCIvar:
4649 case Decl::ObjCAtDefsField:
4650 case Decl::ImplicitParam:
4651 case Decl::ParmVar:
4652 case Decl::NonTypeTemplateParm:
4653 case Decl::TemplateTemplateParm:
4654 case Decl::ObjCCategoryImpl:
4655 case Decl::ObjCImplementation:
4656 case Decl::AccessSpec:
4657 case Decl::LinkageSpec:
4658 case Decl::ObjCPropertyImpl:
4659 case Decl::FileScopeAsm:
4660 case Decl::StaticAssert:
4661 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004662 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 case Decl::Label: // FIXME: Is this right??
4664 case Decl::ClassScopeFunctionSpecialization:
4665 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004666 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004667 return C;
4668
4669 // Declaration kinds that don't make any sense here, but are
4670 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004671 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004672 case Decl::TranslationUnit:
4673 break;
4674
4675 // Declaration kinds for which the definition is not resolvable.
4676 case Decl::UnresolvedUsingTypename:
4677 case Decl::UnresolvedUsingValue:
4678 break;
4679
4680 case Decl::UsingDirective:
4681 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4682 TU);
4683
4684 case Decl::NamespaceAlias:
4685 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4686
4687 case Decl::Enum:
4688 case Decl::Record:
4689 case Decl::CXXRecord:
4690 case Decl::ClassTemplateSpecialization:
4691 case Decl::ClassTemplatePartialSpecialization:
4692 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4693 return MakeCXCursor(Def, TU);
4694 return clang_getNullCursor();
4695
4696 case Decl::Function:
4697 case Decl::CXXMethod:
4698 case Decl::CXXConstructor:
4699 case Decl::CXXDestructor:
4700 case Decl::CXXConversion: {
4701 const FunctionDecl *Def = 0;
4702 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004703 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004704 return clang_getNullCursor();
4705 }
4706
Larisse Voufo39a1e502013-08-06 01:03:05 +00004707 case Decl::Var:
4708 case Decl::VarTemplateSpecialization:
4709 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004710 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004711 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004712 return MakeCXCursor(Def, TU);
4713 return clang_getNullCursor();
4714 }
4715
4716 case Decl::FunctionTemplate: {
4717 const FunctionDecl *Def = 0;
4718 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4719 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4720 return clang_getNullCursor();
4721 }
4722
4723 case Decl::ClassTemplate: {
4724 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4725 ->getDefinition())
4726 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4727 TU);
4728 return clang_getNullCursor();
4729 }
4730
Larisse Voufo39a1e502013-08-06 01:03:05 +00004731 case Decl::VarTemplate: {
4732 if (VarDecl *Def =
4733 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4734 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4735 return clang_getNullCursor();
4736 }
4737
Guy Benyei11169dd2012-12-18 14:30:41 +00004738 case Decl::Using:
4739 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4740 D->getLocation(), TU);
4741
4742 case Decl::UsingShadow:
4743 return clang_getCursorDefinition(
4744 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4745 TU));
4746
4747 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004748 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004749 if (Method->isThisDeclarationADefinition())
4750 return C;
4751
4752 // Dig out the method definition in the associated
4753 // @implementation, if we have it.
4754 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004755 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004756 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4757 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4758 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4759 Method->isInstanceMethod()))
4760 if (Def->isThisDeclarationADefinition())
4761 return MakeCXCursor(Def, TU);
4762
4763 return clang_getNullCursor();
4764 }
4765
4766 case Decl::ObjCCategory:
4767 if (ObjCCategoryImplDecl *Impl
4768 = cast<ObjCCategoryDecl>(D)->getImplementation())
4769 return MakeCXCursor(Impl, TU);
4770 return clang_getNullCursor();
4771
4772 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004773 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004774 return MakeCXCursor(Def, TU);
4775 return clang_getNullCursor();
4776
4777 case Decl::ObjCInterface: {
4778 // There are two notions of a "definition" for an Objective-C
4779 // class: the interface and its implementation. When we resolved a
4780 // reference to an Objective-C class, produce the @interface as
4781 // the definition; when we were provided with the interface,
4782 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004783 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004784 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004785 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004786 return MakeCXCursor(Def, TU);
4787 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4788 return MakeCXCursor(Impl, TU);
4789 return clang_getNullCursor();
4790 }
4791
4792 case Decl::ObjCProperty:
4793 // FIXME: We don't really know where to find the
4794 // ObjCPropertyImplDecls that implement this property.
4795 return clang_getNullCursor();
4796
4797 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004798 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004799 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004800 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004801 return MakeCXCursor(Def, TU);
4802
4803 return clang_getNullCursor();
4804
4805 case Decl::Friend:
4806 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4807 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4808 return clang_getNullCursor();
4809
4810 case Decl::FriendTemplate:
4811 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4812 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4813 return clang_getNullCursor();
4814 }
4815
4816 return clang_getNullCursor();
4817}
4818
4819unsigned clang_isCursorDefinition(CXCursor C) {
4820 if (!clang_isDeclaration(C.kind))
4821 return 0;
4822
4823 return clang_getCursorDefinition(C) == C;
4824}
4825
4826CXCursor clang_getCanonicalCursor(CXCursor C) {
4827 if (!clang_isDeclaration(C.kind))
4828 return C;
4829
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004830 if (const Decl *D = getCursorDecl(C)) {
4831 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004832 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4833 return MakeCXCursor(CatD, getCursorTU(C));
4834
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004835 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4836 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004837 return MakeCXCursor(IFD, getCursorTU(C));
4838
4839 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4840 }
4841
4842 return C;
4843}
4844
4845int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4846 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4847}
4848
4849unsigned clang_getNumOverloadedDecls(CXCursor C) {
4850 if (C.kind != CXCursor_OverloadedDeclRef)
4851 return 0;
4852
4853 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004854 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004855 return E->getNumDecls();
4856
4857 if (OverloadedTemplateStorage *S
4858 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4859 return S->size();
4860
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004861 const Decl *D = Storage.get<const Decl *>();
4862 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004863 return Using->shadow_size();
4864
4865 return 0;
4866}
4867
4868CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4869 if (cursor.kind != CXCursor_OverloadedDeclRef)
4870 return clang_getNullCursor();
4871
4872 if (index >= clang_getNumOverloadedDecls(cursor))
4873 return clang_getNullCursor();
4874
4875 CXTranslationUnit TU = getCursorTU(cursor);
4876 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004877 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004878 return MakeCXCursor(E->decls_begin()[index], TU);
4879
4880 if (OverloadedTemplateStorage *S
4881 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4882 return MakeCXCursor(S->begin()[index], TU);
4883
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004884 const Decl *D = Storage.get<const Decl *>();
4885 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004886 // FIXME: This is, unfortunately, linear time.
4887 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4888 std::advance(Pos, index);
4889 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4890 }
4891
4892 return clang_getNullCursor();
4893}
4894
4895void clang_getDefinitionSpellingAndExtent(CXCursor C,
4896 const char **startBuf,
4897 const char **endBuf,
4898 unsigned *startLine,
4899 unsigned *startColumn,
4900 unsigned *endLine,
4901 unsigned *endColumn) {
4902 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004903 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004904 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4905
4906 SourceManager &SM = FD->getASTContext().getSourceManager();
4907 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4908 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4909 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4910 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4911 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4912 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4913}
4914
4915
4916CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4917 unsigned PieceIndex) {
4918 RefNamePieces Pieces;
4919
4920 switch (C.kind) {
4921 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004922 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004923 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4924 E->getQualifierLoc().getSourceRange());
4925 break;
4926
4927 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004928 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004929 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4930 E->getQualifierLoc().getSourceRange(),
4931 E->getOptionalExplicitTemplateArgs());
4932 break;
4933
4934 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004935 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004936 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004937 const Expr *Callee = OCE->getCallee();
4938 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004939 Callee = ICE->getSubExpr();
4940
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004941 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004942 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4943 DRE->getQualifierLoc().getSourceRange());
4944 }
4945 break;
4946
4947 default:
4948 break;
4949 }
4950
4951 if (Pieces.empty()) {
4952 if (PieceIndex == 0)
4953 return clang_getCursorExtent(C);
4954 } else if (PieceIndex < Pieces.size()) {
4955 SourceRange R = Pieces[PieceIndex];
4956 if (R.isValid())
4957 return cxloc::translateSourceRange(getCursorContext(C), R);
4958 }
4959
4960 return clang_getNullRange();
4961}
4962
4963void clang_enableStackTraces(void) {
4964 llvm::sys::PrintStackTraceOnErrorSignal();
4965}
4966
4967void clang_executeOnThread(void (*fn)(void*), void *user_data,
4968 unsigned stack_size) {
4969 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4970}
4971
4972} // end: extern "C"
4973
4974//===----------------------------------------------------------------------===//
4975// Token-based Operations.
4976//===----------------------------------------------------------------------===//
4977
4978/* CXToken layout:
4979 * int_data[0]: a CXTokenKind
4980 * int_data[1]: starting token location
4981 * int_data[2]: token length
4982 * int_data[3]: reserved
4983 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4984 * otherwise unused.
4985 */
4986extern "C" {
4987
4988CXTokenKind clang_getTokenKind(CXToken CXTok) {
4989 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4990}
4991
4992CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4993 switch (clang_getTokenKind(CXTok)) {
4994 case CXToken_Identifier:
4995 case CXToken_Keyword:
4996 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004997 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004998 ->getNameStart());
4999
5000 case CXToken_Literal: {
5001 // We have stashed the starting pointer in the ptr_data field. Use it.
5002 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005003 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005004 }
5005
5006 case CXToken_Punctuation:
5007 case CXToken_Comment:
5008 break;
5009 }
5010
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005011 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005012 LOG_BAD_TU(TU);
5013 return cxstring::createEmpty();
5014 }
5015
Guy Benyei11169dd2012-12-18 14:30:41 +00005016 // We have to find the starting buffer pointer the hard way, by
5017 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005018 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005019 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005020 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005021
5022 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5023 std::pair<FileID, unsigned> LocInfo
5024 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5025 bool Invalid = false;
5026 StringRef Buffer
5027 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5028 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005029 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005030
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005031 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005032}
5033
5034CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005035 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005036 LOG_BAD_TU(TU);
5037 return clang_getNullLocation();
5038 }
5039
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005040 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005041 if (!CXXUnit)
5042 return clang_getNullLocation();
5043
5044 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5045 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5046}
5047
5048CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005049 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005050 LOG_BAD_TU(TU);
5051 return clang_getNullRange();
5052 }
5053
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005054 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005055 if (!CXXUnit)
5056 return clang_getNullRange();
5057
5058 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5059 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5060}
5061
5062static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5063 SmallVectorImpl<CXToken> &CXTokens) {
5064 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5065 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005066 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005067 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005068 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005069
5070 // Cannot tokenize across files.
5071 if (BeginLocInfo.first != EndLocInfo.first)
5072 return;
5073
5074 // Create a lexer
5075 bool Invalid = false;
5076 StringRef Buffer
5077 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5078 if (Invalid)
5079 return;
5080
5081 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5082 CXXUnit->getASTContext().getLangOpts(),
5083 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5084 Lex.SetCommentRetentionState(true);
5085
5086 // Lex tokens until we hit the end of the range.
5087 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5088 Token Tok;
5089 bool previousWasAt = false;
5090 do {
5091 // Lex the next token
5092 Lex.LexFromRawLexer(Tok);
5093 if (Tok.is(tok::eof))
5094 break;
5095
5096 // Initialize the CXToken.
5097 CXToken CXTok;
5098
5099 // - Common fields
5100 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5101 CXTok.int_data[2] = Tok.getLength();
5102 CXTok.int_data[3] = 0;
5103
5104 // - Kind-specific fields
5105 if (Tok.isLiteral()) {
5106 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005107 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005108 } else if (Tok.is(tok::raw_identifier)) {
5109 // Lookup the identifier to determine whether we have a keyword.
5110 IdentifierInfo *II
5111 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5112
5113 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5114 CXTok.int_data[0] = CXToken_Keyword;
5115 }
5116 else {
5117 CXTok.int_data[0] = Tok.is(tok::identifier)
5118 ? CXToken_Identifier
5119 : CXToken_Keyword;
5120 }
5121 CXTok.ptr_data = II;
5122 } else if (Tok.is(tok::comment)) {
5123 CXTok.int_data[0] = CXToken_Comment;
5124 CXTok.ptr_data = 0;
5125 } else {
5126 CXTok.int_data[0] = CXToken_Punctuation;
5127 CXTok.ptr_data = 0;
5128 }
5129 CXTokens.push_back(CXTok);
5130 previousWasAt = Tok.is(tok::at);
5131 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5132}
5133
5134void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5135 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005136 LOG_FUNC_SECTION {
5137 *Log << TU << ' ' << Range;
5138 }
5139
Guy Benyei11169dd2012-12-18 14:30:41 +00005140 if (Tokens)
5141 *Tokens = 0;
5142 if (NumTokens)
5143 *NumTokens = 0;
5144
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005145 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005146 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005147 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005148 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005149
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005150 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005151 if (!CXXUnit || !Tokens || !NumTokens)
5152 return;
5153
5154 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5155
5156 SourceRange R = cxloc::translateCXSourceRange(Range);
5157 if (R.isInvalid())
5158 return;
5159
5160 SmallVector<CXToken, 32> CXTokens;
5161 getTokens(CXXUnit, R, CXTokens);
5162
5163 if (CXTokens.empty())
5164 return;
5165
5166 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5167 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5168 *NumTokens = CXTokens.size();
5169}
5170
5171void clang_disposeTokens(CXTranslationUnit TU,
5172 CXToken *Tokens, unsigned NumTokens) {
5173 free(Tokens);
5174}
5175
5176} // end: extern "C"
5177
5178//===----------------------------------------------------------------------===//
5179// Token annotation APIs.
5180//===----------------------------------------------------------------------===//
5181
Guy Benyei11169dd2012-12-18 14:30:41 +00005182static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5183 CXCursor parent,
5184 CXClientData client_data);
5185static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5186 CXClientData client_data);
5187
5188namespace {
5189class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005190 CXToken *Tokens;
5191 CXCursor *Cursors;
5192 unsigned NumTokens;
5193 unsigned TokIdx;
5194 unsigned PreprocessingTokIdx;
5195 CursorVisitor AnnotateVis;
5196 SourceManager &SrcMgr;
5197 bool HasContextSensitiveKeywords;
5198
5199 struct PostChildrenInfo {
5200 CXCursor Cursor;
5201 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005202 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005203 unsigned BeforeChildrenTokenIdx;
5204 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005205 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005206
5207 CXToken &getTok(unsigned Idx) {
5208 assert(Idx < NumTokens);
5209 return Tokens[Idx];
5210 }
5211 const CXToken &getTok(unsigned Idx) const {
5212 assert(Idx < NumTokens);
5213 return Tokens[Idx];
5214 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005215 bool MoreTokens() const { return TokIdx < NumTokens; }
5216 unsigned NextToken() const { return TokIdx; }
5217 void AdvanceToken() { ++TokIdx; }
5218 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005219 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005220 }
5221 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005222 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005223 }
5224 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005225 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005226 }
5227
5228 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005229 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005230 SourceRange);
5231
5232public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005233 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005234 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005235 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005236 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005237 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005238 AnnotateTokensVisitor, this,
5239 /*VisitPreprocessorLast=*/true,
5240 /*VisitIncludedEntities=*/false,
5241 RegionOfInterest,
5242 /*VisitDeclsOnly=*/false,
5243 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005244 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005245 HasContextSensitiveKeywords(false) { }
5246
5247 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5248 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5249 bool postVisitChildren(CXCursor cursor);
5250 void AnnotateTokens();
5251
5252 /// \brief Determine whether the annotator saw any cursors that have
5253 /// context-sensitive keywords.
5254 bool hasContextSensitiveKeywords() const {
5255 return HasContextSensitiveKeywords;
5256 }
5257
5258 ~AnnotateTokensWorker() {
5259 assert(PostChildrenInfos.empty());
5260 }
5261};
5262}
5263
5264void AnnotateTokensWorker::AnnotateTokens() {
5265 // Walk the AST within the region of interest, annotating tokens
5266 // along the way.
5267 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005268}
Guy Benyei11169dd2012-12-18 14:30:41 +00005269
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005270static inline void updateCursorAnnotation(CXCursor &Cursor,
5271 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005272 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005273 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005274 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005275}
5276
5277/// \brief It annotates and advances tokens with a cursor until the comparison
5278//// between the cursor location and the source range is the same as
5279/// \arg compResult.
5280///
5281/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5282/// Pass RangeOverlap to annotate tokens inside a range.
5283void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5284 RangeComparisonResult compResult,
5285 SourceRange range) {
5286 while (MoreTokens()) {
5287 const unsigned I = NextToken();
5288 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005289 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5290 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005291
5292 SourceLocation TokLoc = GetTokenLoc(I);
5293 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005294 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005295 AdvanceToken();
5296 continue;
5297 }
5298 break;
5299 }
5300}
5301
5302/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005303/// \returns true if it advanced beyond all macro tokens, false otherwise.
5304bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005305 CXCursor updateC,
5306 RangeComparisonResult compResult,
5307 SourceRange range) {
5308 assert(MoreTokens());
5309 assert(isFunctionMacroToken(NextToken()) &&
5310 "Should be called only for macro arg tokens");
5311
5312 // This works differently than annotateAndAdvanceTokens; because expanded
5313 // macro arguments can have arbitrary translation-unit source order, we do not
5314 // advance the token index one by one until a token fails the range test.
5315 // We only advance once past all of the macro arg tokens if all of them
5316 // pass the range test. If one of them fails we keep the token index pointing
5317 // at the start of the macro arg tokens so that the failing token will be
5318 // annotated by a subsequent annotation try.
5319
5320 bool atLeastOneCompFail = false;
5321
5322 unsigned I = NextToken();
5323 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5324 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5325 if (TokLoc.isFileID())
5326 continue; // not macro arg token, it's parens or comma.
5327 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5328 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5329 Cursors[I] = updateC;
5330 } else
5331 atLeastOneCompFail = true;
5332 }
5333
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005334 if (atLeastOneCompFail)
5335 return false;
5336
5337 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5338 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005339}
5340
5341enum CXChildVisitResult
5342AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005343 SourceRange cursorRange = getRawCursorExtent(cursor);
5344 if (cursorRange.isInvalid())
5345 return CXChildVisit_Recurse;
5346
5347 if (!HasContextSensitiveKeywords) {
5348 // Objective-C properties can have context-sensitive keywords.
5349 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005350 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005351 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5352 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5353 }
5354 // Objective-C methods can have context-sensitive keywords.
5355 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5356 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005357 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005358 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5359 if (Method->getObjCDeclQualifier())
5360 HasContextSensitiveKeywords = true;
5361 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005362 for (const auto *P : Method->params()) {
5363 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005364 HasContextSensitiveKeywords = true;
5365 break;
5366 }
5367 }
5368 }
5369 }
5370 }
5371 // C++ methods can have context-sensitive keywords.
5372 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005373 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005374 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5375 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5376 HasContextSensitiveKeywords = true;
5377 }
5378 }
5379 // C++ classes can have context-sensitive keywords.
5380 else if (cursor.kind == CXCursor_StructDecl ||
5381 cursor.kind == CXCursor_ClassDecl ||
5382 cursor.kind == CXCursor_ClassTemplate ||
5383 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005384 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005385 if (D->hasAttr<FinalAttr>())
5386 HasContextSensitiveKeywords = true;
5387 }
5388 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005389
5390 // Don't override a property annotation with its getter/setter method.
5391 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5392 parent.kind == CXCursor_ObjCPropertyDecl)
5393 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005394
5395 if (clang_isPreprocessing(cursor.kind)) {
5396 // Items in the preprocessing record are kept separate from items in
5397 // declarations, so we keep a separate token index.
5398 unsigned SavedTokIdx = TokIdx;
5399 TokIdx = PreprocessingTokIdx;
5400
5401 // Skip tokens up until we catch up to the beginning of the preprocessing
5402 // entry.
5403 while (MoreTokens()) {
5404 const unsigned I = NextToken();
5405 SourceLocation TokLoc = GetTokenLoc(I);
5406 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5407 case RangeBefore:
5408 AdvanceToken();
5409 continue;
5410 case RangeAfter:
5411 case RangeOverlap:
5412 break;
5413 }
5414 break;
5415 }
5416
5417 // Look at all of the tokens within this range.
5418 while (MoreTokens()) {
5419 const unsigned I = NextToken();
5420 SourceLocation TokLoc = GetTokenLoc(I);
5421 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5422 case RangeBefore:
5423 llvm_unreachable("Infeasible");
5424 case RangeAfter:
5425 break;
5426 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005427 // For macro expansions, just note where the beginning of the macro
5428 // expansion occurs.
5429 if (cursor.kind == CXCursor_MacroExpansion) {
5430 if (TokLoc == cursorRange.getBegin())
5431 Cursors[I] = cursor;
5432 AdvanceToken();
5433 break;
5434 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005435 // We may have already annotated macro names inside macro definitions.
5436 if (Cursors[I].kind != CXCursor_MacroExpansion)
5437 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005438 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005439 continue;
5440 }
5441 break;
5442 }
5443
5444 // Save the preprocessing token index; restore the non-preprocessing
5445 // token index.
5446 PreprocessingTokIdx = TokIdx;
5447 TokIdx = SavedTokIdx;
5448 return CXChildVisit_Recurse;
5449 }
5450
5451 if (cursorRange.isInvalid())
5452 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005453
5454 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005455 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005456 const enum CXCursorKind K = clang_getCursorKind(parent);
5457 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005458 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5459 // Attributes are annotated out-of-order, skip tokens until we reach it.
5460 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005461 ? clang_getNullCursor() : parent;
5462
5463 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5464
5465 // Avoid having the cursor of an expression "overwrite" the annotation of the
5466 // variable declaration that it belongs to.
5467 // This can happen for C++ constructor expressions whose range generally
5468 // include the variable declaration, e.g.:
5469 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005470 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005471 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005472 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005473 const unsigned I = NextToken();
5474 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5475 E->getLocStart() == D->getLocation() &&
5476 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005477 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005478 AdvanceToken();
5479 }
5480 }
5481 }
5482
5483 // Before recursing into the children keep some state that we are going
5484 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5485 // extra work after the child nodes are visited.
5486 // Note that we don't call VisitChildren here to avoid traversing statements
5487 // code-recursively which can blow the stack.
5488
5489 PostChildrenInfo Info;
5490 Info.Cursor = cursor;
5491 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005492 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005493 Info.BeforeChildrenTokenIdx = NextToken();
5494 PostChildrenInfos.push_back(Info);
5495
5496 return CXChildVisit_Recurse;
5497}
5498
5499bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5500 if (PostChildrenInfos.empty())
5501 return false;
5502 const PostChildrenInfo &Info = PostChildrenInfos.back();
5503 if (!clang_equalCursors(Info.Cursor, cursor))
5504 return false;
5505
5506 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5507 const unsigned AfterChildren = NextToken();
5508 SourceRange cursorRange = Info.CursorRange;
5509
5510 // Scan the tokens that are at the end of the cursor, but are not captured
5511 // but the child cursors.
5512 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5513
5514 // Scan the tokens that are at the beginning of the cursor, but are not
5515 // capture by the child cursors.
5516 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5517 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5518 break;
5519
5520 Cursors[I] = cursor;
5521 }
5522
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005523 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5524 // encountered the attribute cursor.
5525 if (clang_isAttribute(cursor.kind))
5526 TokIdx = Info.BeforeReachingCursorIdx;
5527
Guy Benyei11169dd2012-12-18 14:30:41 +00005528 PostChildrenInfos.pop_back();
5529 return false;
5530}
5531
5532static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5533 CXCursor parent,
5534 CXClientData client_data) {
5535 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5536}
5537
5538static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5539 CXClientData client_data) {
5540 return static_cast<AnnotateTokensWorker*>(client_data)->
5541 postVisitChildren(cursor);
5542}
5543
5544namespace {
5545
5546/// \brief Uses the macro expansions in the preprocessing record to find
5547/// and mark tokens that are macro arguments. This info is used by the
5548/// AnnotateTokensWorker.
5549class MarkMacroArgTokensVisitor {
5550 SourceManager &SM;
5551 CXToken *Tokens;
5552 unsigned NumTokens;
5553 unsigned CurIdx;
5554
5555public:
5556 MarkMacroArgTokensVisitor(SourceManager &SM,
5557 CXToken *tokens, unsigned numTokens)
5558 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5559
5560 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5561 if (cursor.kind != CXCursor_MacroExpansion)
5562 return CXChildVisit_Continue;
5563
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005564 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005565 if (macroRange.getBegin() == macroRange.getEnd())
5566 return CXChildVisit_Continue; // it's not a function macro.
5567
5568 for (; CurIdx < NumTokens; ++CurIdx) {
5569 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5570 macroRange.getBegin()))
5571 break;
5572 }
5573
5574 if (CurIdx == NumTokens)
5575 return CXChildVisit_Break;
5576
5577 for (; CurIdx < NumTokens; ++CurIdx) {
5578 SourceLocation tokLoc = getTokenLoc(CurIdx);
5579 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5580 break;
5581
5582 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5583 }
5584
5585 if (CurIdx == NumTokens)
5586 return CXChildVisit_Break;
5587
5588 return CXChildVisit_Continue;
5589 }
5590
5591private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005592 CXToken &getTok(unsigned Idx) {
5593 assert(Idx < NumTokens);
5594 return Tokens[Idx];
5595 }
5596 const CXToken &getTok(unsigned Idx) const {
5597 assert(Idx < NumTokens);
5598 return Tokens[Idx];
5599 }
5600
Guy Benyei11169dd2012-12-18 14:30:41 +00005601 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005602 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005603 }
5604
5605 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5606 // The third field is reserved and currently not used. Use it here
5607 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005608 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005609 }
5610};
5611
5612} // end anonymous namespace
5613
5614static CXChildVisitResult
5615MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5616 CXClientData client_data) {
5617 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5618 parent);
5619}
5620
5621namespace {
5622 struct clang_annotateTokens_Data {
5623 CXTranslationUnit TU;
5624 ASTUnit *CXXUnit;
5625 CXToken *Tokens;
5626 unsigned NumTokens;
5627 CXCursor *Cursors;
5628 };
5629}
5630
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005631/// \brief Used by \c annotatePreprocessorTokens.
5632/// \returns true if lexing was finished, false otherwise.
5633static bool lexNext(Lexer &Lex, Token &Tok,
5634 unsigned &NextIdx, unsigned NumTokens) {
5635 if (NextIdx >= NumTokens)
5636 return true;
5637
5638 ++NextIdx;
5639 Lex.LexFromRawLexer(Tok);
5640 if (Tok.is(tok::eof))
5641 return true;
5642
5643 return false;
5644}
5645
Guy Benyei11169dd2012-12-18 14:30:41 +00005646static void annotatePreprocessorTokens(CXTranslationUnit TU,
5647 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005648 CXCursor *Cursors,
5649 CXToken *Tokens,
5650 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005651 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005652
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005653 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005654 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5655 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005656 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005657 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005658 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005659
5660 if (BeginLocInfo.first != EndLocInfo.first)
5661 return;
5662
5663 StringRef Buffer;
5664 bool Invalid = false;
5665 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5666 if (Buffer.empty() || Invalid)
5667 return;
5668
5669 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5670 CXXUnit->getASTContext().getLangOpts(),
5671 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5672 Buffer.end());
5673 Lex.SetCommentRetentionState(true);
5674
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005675 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005676 // Lex tokens in raw mode until we hit the end of the range, to avoid
5677 // entering #includes or expanding macros.
5678 while (true) {
5679 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005680 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5681 break;
5682 unsigned TokIdx = NextIdx-1;
5683 assert(Tok.getLocation() ==
5684 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005685
5686 reprocess:
5687 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005688 // We have found a preprocessing directive. Annotate the tokens
5689 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005690 //
5691 // FIXME: Some simple tests here could identify macro definitions and
5692 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005693
5694 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005695 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5696 break;
5697
5698 MacroInfo *MI = 0;
5699 if (Tok.is(tok::raw_identifier) &&
5700 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5701 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5702 break;
5703
5704 if (Tok.is(tok::raw_identifier)) {
5705 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5706 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5707 SourceLocation MappedTokLoc =
5708 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5709 MI = getMacroInfo(II, MappedTokLoc, TU);
5710 }
5711 }
5712
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005713 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005714 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005715 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5716 finished = true;
5717 break;
5718 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005719 // If we are in a macro definition, check if the token was ever a
5720 // macro name and annotate it if that's the case.
5721 if (MI) {
5722 SourceLocation SaveLoc = Tok.getLocation();
5723 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5724 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5725 Tok.setLocation(SaveLoc);
5726 if (MacroDef)
5727 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5728 Tok.getLocation(), TU);
5729 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005730 } while (!Tok.isAtStartOfLine());
5731
5732 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5733 assert(TokIdx <= LastIdx);
5734 SourceLocation EndLoc =
5735 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5736 CXCursor Cursor =
5737 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5738
5739 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005740 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005741
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005742 if (finished)
5743 break;
5744 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005745 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005746 }
5747}
5748
5749// This gets run a separate thread to avoid stack blowout.
5750static void clang_annotateTokensImpl(void *UserData) {
5751 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5752 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5753 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5754 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5755 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5756
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005757 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005758 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5759 setThreadBackgroundPriority();
5760
5761 // Determine the region of interest, which contains all of the tokens.
5762 SourceRange RegionOfInterest;
5763 RegionOfInterest.setBegin(
5764 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5765 RegionOfInterest.setEnd(
5766 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5767 Tokens[NumTokens-1])));
5768
Guy Benyei11169dd2012-12-18 14:30:41 +00005769 // Relex the tokens within the source range to look for preprocessing
5770 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005771 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005772
5773 // If begin location points inside a macro argument, set it to the expansion
5774 // location so we can have the full context when annotating semantically.
5775 {
5776 SourceManager &SM = CXXUnit->getSourceManager();
5777 SourceLocation Loc =
5778 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5779 if (Loc.isMacroID())
5780 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5781 }
5782
Guy Benyei11169dd2012-12-18 14:30:41 +00005783 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5784 // Search and mark tokens that are macro argument expansions.
5785 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5786 Tokens, NumTokens);
5787 CursorVisitor MacroArgMarker(TU,
5788 MarkMacroArgTokensVisitorDelegate, &Visitor,
5789 /*VisitPreprocessorLast=*/true,
5790 /*VisitIncludedEntities=*/false,
5791 RegionOfInterest);
5792 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5793 }
5794
5795 // Annotate all of the source locations in the region of interest that map to
5796 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005797 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005798
5799 // FIXME: We use a ridiculous stack size here because the data-recursion
5800 // algorithm uses a large stack frame than the non-data recursive version,
5801 // and AnnotationTokensWorker currently transforms the data-recursion
5802 // algorithm back into a traditional recursion by explicitly calling
5803 // VisitChildren(). We will need to remove this explicit recursive call.
5804 W.AnnotateTokens();
5805
5806 // If we ran into any entities that involve context-sensitive keywords,
5807 // take another pass through the tokens to mark them as such.
5808 if (W.hasContextSensitiveKeywords()) {
5809 for (unsigned I = 0; I != NumTokens; ++I) {
5810 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5811 continue;
5812
5813 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5814 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005815 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005816 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5817 if (Property->getPropertyAttributesAsWritten() != 0 &&
5818 llvm::StringSwitch<bool>(II->getName())
5819 .Case("readonly", true)
5820 .Case("assign", true)
5821 .Case("unsafe_unretained", true)
5822 .Case("readwrite", true)
5823 .Case("retain", true)
5824 .Case("copy", true)
5825 .Case("nonatomic", true)
5826 .Case("atomic", true)
5827 .Case("getter", true)
5828 .Case("setter", true)
5829 .Case("strong", true)
5830 .Case("weak", true)
5831 .Default(false))
5832 Tokens[I].int_data[0] = CXToken_Keyword;
5833 }
5834 continue;
5835 }
5836
5837 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5838 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5839 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5840 if (llvm::StringSwitch<bool>(II->getName())
5841 .Case("in", true)
5842 .Case("out", true)
5843 .Case("inout", true)
5844 .Case("oneway", true)
5845 .Case("bycopy", true)
5846 .Case("byref", true)
5847 .Default(false))
5848 Tokens[I].int_data[0] = CXToken_Keyword;
5849 continue;
5850 }
5851
5852 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5853 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5854 Tokens[I].int_data[0] = CXToken_Keyword;
5855 continue;
5856 }
5857 }
5858 }
5859}
5860
5861extern "C" {
5862
5863void clang_annotateTokens(CXTranslationUnit TU,
5864 CXToken *Tokens, unsigned NumTokens,
5865 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005866 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005867 LOG_BAD_TU(TU);
5868 return;
5869 }
5870 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005871 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005872 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005873 }
5874
5875 LOG_FUNC_SECTION {
5876 *Log << TU << ' ';
5877 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5878 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5879 *Log << clang_getRange(bloc, eloc);
5880 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005881
5882 // Any token we don't specifically annotate will have a NULL cursor.
5883 CXCursor C = clang_getNullCursor();
5884 for (unsigned I = 0; I != NumTokens; ++I)
5885 Cursors[I] = C;
5886
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005887 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005888 if (!CXXUnit)
5889 return;
5890
5891 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5892
5893 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5894 llvm::CrashRecoveryContext CRC;
5895 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5896 GetSafetyThreadStackSize() * 2)) {
5897 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5898 }
5899}
5900
5901} // end: extern "C"
5902
5903//===----------------------------------------------------------------------===//
5904// Operations for querying linkage of a cursor.
5905//===----------------------------------------------------------------------===//
5906
5907extern "C" {
5908CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5909 if (!clang_isDeclaration(cursor.kind))
5910 return CXLinkage_Invalid;
5911
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005912 const Decl *D = cxcursor::getCursorDecl(cursor);
5913 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005914 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005915 case NoLinkage:
5916 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005917 case InternalLinkage: return CXLinkage_Internal;
5918 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5919 case ExternalLinkage: return CXLinkage_External;
5920 };
5921
5922 return CXLinkage_Invalid;
5923}
5924} // end: extern "C"
5925
5926//===----------------------------------------------------------------------===//
5927// Operations for querying language of a cursor.
5928//===----------------------------------------------------------------------===//
5929
5930static CXLanguageKind getDeclLanguage(const Decl *D) {
5931 if (!D)
5932 return CXLanguage_C;
5933
5934 switch (D->getKind()) {
5935 default:
5936 break;
5937 case Decl::ImplicitParam:
5938 case Decl::ObjCAtDefsField:
5939 case Decl::ObjCCategory:
5940 case Decl::ObjCCategoryImpl:
5941 case Decl::ObjCCompatibleAlias:
5942 case Decl::ObjCImplementation:
5943 case Decl::ObjCInterface:
5944 case Decl::ObjCIvar:
5945 case Decl::ObjCMethod:
5946 case Decl::ObjCProperty:
5947 case Decl::ObjCPropertyImpl:
5948 case Decl::ObjCProtocol:
5949 return CXLanguage_ObjC;
5950 case Decl::CXXConstructor:
5951 case Decl::CXXConversion:
5952 case Decl::CXXDestructor:
5953 case Decl::CXXMethod:
5954 case Decl::CXXRecord:
5955 case Decl::ClassTemplate:
5956 case Decl::ClassTemplatePartialSpecialization:
5957 case Decl::ClassTemplateSpecialization:
5958 case Decl::Friend:
5959 case Decl::FriendTemplate:
5960 case Decl::FunctionTemplate:
5961 case Decl::LinkageSpec:
5962 case Decl::Namespace:
5963 case Decl::NamespaceAlias:
5964 case Decl::NonTypeTemplateParm:
5965 case Decl::StaticAssert:
5966 case Decl::TemplateTemplateParm:
5967 case Decl::TemplateTypeParm:
5968 case Decl::UnresolvedUsingTypename:
5969 case Decl::UnresolvedUsingValue:
5970 case Decl::Using:
5971 case Decl::UsingDirective:
5972 case Decl::UsingShadow:
5973 return CXLanguage_CPlusPlus;
5974 }
5975
5976 return CXLanguage_C;
5977}
5978
5979extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005980
5981static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5982 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5983 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005984
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005985 switch (D->getAvailability()) {
5986 case AR_Available:
5987 case AR_NotYetIntroduced:
5988 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005989 return getCursorAvailabilityForDecl(
5990 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005991 return CXAvailability_Available;
5992
5993 case AR_Deprecated:
5994 return CXAvailability_Deprecated;
5995
5996 case AR_Unavailable:
5997 return CXAvailability_NotAvailable;
5998 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005999
6000 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006001}
6002
Guy Benyei11169dd2012-12-18 14:30:41 +00006003enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6004 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006005 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6006 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006007
6008 return CXAvailability_Available;
6009}
6010
6011static CXVersion convertVersion(VersionTuple In) {
6012 CXVersion Out = { -1, -1, -1 };
6013 if (In.empty())
6014 return Out;
6015
6016 Out.Major = In.getMajor();
6017
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006018 Optional<unsigned> Minor = In.getMinor();
6019 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006020 Out.Minor = *Minor;
6021 else
6022 return Out;
6023
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006024 Optional<unsigned> Subminor = In.getSubminor();
6025 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006026 Out.Subminor = *Subminor;
6027
6028 return Out;
6029}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006030
6031static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6032 int *always_deprecated,
6033 CXString *deprecated_message,
6034 int *always_unavailable,
6035 CXString *unavailable_message,
6036 CXPlatformAvailability *availability,
6037 int availability_size) {
6038 bool HadAvailAttr = false;
6039 int N = 0;
Aaron Ballman7dce1a82014-03-07 13:13:38 +00006040 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
6041 ++A) {
6042 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006043 HadAvailAttr = true;
6044 if (always_deprecated)
6045 *always_deprecated = 1;
6046 if (deprecated_message)
6047 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
6048 continue;
6049 }
6050
Aaron Ballman7dce1a82014-03-07 13:13:38 +00006051 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006052 HadAvailAttr = true;
6053 if (always_unavailable)
6054 *always_unavailable = 1;
6055 if (unavailable_message) {
6056 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6057 }
6058 continue;
6059 }
6060
Aaron Ballman7dce1a82014-03-07 13:13:38 +00006061 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006062 HadAvailAttr = true;
6063 if (N < availability_size) {
6064 availability[N].Platform
6065 = cxstring::createDup(Avail->getPlatform()->getName());
6066 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6067 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6068 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6069 availability[N].Unavailable = Avail->getUnavailable();
6070 availability[N].Message = cxstring::createDup(Avail->getMessage());
6071 }
6072 ++N;
6073 }
6074 }
6075
6076 if (!HadAvailAttr)
6077 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6078 return getCursorPlatformAvailabilityForDecl(
6079 cast<Decl>(EnumConst->getDeclContext()),
6080 always_deprecated,
6081 deprecated_message,
6082 always_unavailable,
6083 unavailable_message,
6084 availability,
6085 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006086
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006087 return N;
6088}
6089
Guy Benyei11169dd2012-12-18 14:30:41 +00006090int clang_getCursorPlatformAvailability(CXCursor cursor,
6091 int *always_deprecated,
6092 CXString *deprecated_message,
6093 int *always_unavailable,
6094 CXString *unavailable_message,
6095 CXPlatformAvailability *availability,
6096 int availability_size) {
6097 if (always_deprecated)
6098 *always_deprecated = 0;
6099 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006100 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006101 if (always_unavailable)
6102 *always_unavailable = 0;
6103 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006104 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006105
Guy Benyei11169dd2012-12-18 14:30:41 +00006106 if (!clang_isDeclaration(cursor.kind))
6107 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006108
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006109 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006110 if (!D)
6111 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006112
6113 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6114 deprecated_message,
6115 always_unavailable,
6116 unavailable_message,
6117 availability,
6118 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006119}
6120
6121void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6122 clang_disposeString(availability->Platform);
6123 clang_disposeString(availability->Message);
6124}
6125
6126CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6127 if (clang_isDeclaration(cursor.kind))
6128 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6129
6130 return CXLanguage_Invalid;
6131}
6132
6133 /// \brief If the given cursor is the "templated" declaration
6134 /// descibing a class or function template, return the class or
6135 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006136static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006137 if (!D)
6138 return 0;
6139
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006140 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006141 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6142 return FunTmpl;
6143
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006144 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006145 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6146 return ClassTmpl;
6147
6148 return D;
6149}
6150
6151CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6152 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006153 if (const Decl *D = getCursorDecl(cursor)) {
6154 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006155 if (!DC)
6156 return clang_getNullCursor();
6157
6158 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6159 getCursorTU(cursor));
6160 }
6161 }
6162
6163 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006164 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006165 return MakeCXCursor(D, getCursorTU(cursor));
6166 }
6167
6168 return clang_getNullCursor();
6169}
6170
6171CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6172 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006173 if (const Decl *D = getCursorDecl(cursor)) {
6174 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006175 if (!DC)
6176 return clang_getNullCursor();
6177
6178 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6179 getCursorTU(cursor));
6180 }
6181 }
6182
6183 // FIXME: Note that we can't easily compute the lexical context of a
6184 // statement or expression, so we return nothing.
6185 return clang_getNullCursor();
6186}
6187
6188CXFile clang_getIncludedFile(CXCursor cursor) {
6189 if (cursor.kind != CXCursor_InclusionDirective)
6190 return 0;
6191
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006192 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006193 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006194}
6195
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006196unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6197 if (C.kind != CXCursor_ObjCPropertyDecl)
6198 return CXObjCPropertyAttr_noattr;
6199
6200 unsigned Result = CXObjCPropertyAttr_noattr;
6201 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6202 ObjCPropertyDecl::PropertyAttributeKind Attr =
6203 PD->getPropertyAttributesAsWritten();
6204
6205#define SET_CXOBJCPROP_ATTR(A) \
6206 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6207 Result |= CXObjCPropertyAttr_##A
6208 SET_CXOBJCPROP_ATTR(readonly);
6209 SET_CXOBJCPROP_ATTR(getter);
6210 SET_CXOBJCPROP_ATTR(assign);
6211 SET_CXOBJCPROP_ATTR(readwrite);
6212 SET_CXOBJCPROP_ATTR(retain);
6213 SET_CXOBJCPROP_ATTR(copy);
6214 SET_CXOBJCPROP_ATTR(nonatomic);
6215 SET_CXOBJCPROP_ATTR(setter);
6216 SET_CXOBJCPROP_ATTR(atomic);
6217 SET_CXOBJCPROP_ATTR(weak);
6218 SET_CXOBJCPROP_ATTR(strong);
6219 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6220#undef SET_CXOBJCPROP_ATTR
6221
6222 return Result;
6223}
6224
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006225unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6226 if (!clang_isDeclaration(C.kind))
6227 return CXObjCDeclQualifier_None;
6228
6229 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6230 const Decl *D = getCursorDecl(C);
6231 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6232 QT = MD->getObjCDeclQualifier();
6233 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6234 QT = PD->getObjCDeclQualifier();
6235 if (QT == Decl::OBJC_TQ_None)
6236 return CXObjCDeclQualifier_None;
6237
6238 unsigned Result = CXObjCDeclQualifier_None;
6239 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6240 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6241 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6242 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6243 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6244 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6245
6246 return Result;
6247}
6248
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006249unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6250 if (!clang_isDeclaration(C.kind))
6251 return 0;
6252
6253 const Decl *D = getCursorDecl(C);
6254 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6255 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6256 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6257 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6258
6259 return 0;
6260}
6261
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006262unsigned clang_Cursor_isVariadic(CXCursor C) {
6263 if (!clang_isDeclaration(C.kind))
6264 return 0;
6265
6266 const Decl *D = getCursorDecl(C);
6267 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6268 return FD->isVariadic();
6269 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6270 return MD->isVariadic();
6271
6272 return 0;
6273}
6274
Guy Benyei11169dd2012-12-18 14:30:41 +00006275CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6276 if (!clang_isDeclaration(C.kind))
6277 return clang_getNullRange();
6278
6279 const Decl *D = getCursorDecl(C);
6280 ASTContext &Context = getCursorContext(C);
6281 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6282 if (!RC)
6283 return clang_getNullRange();
6284
6285 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6286}
6287
6288CXString clang_Cursor_getRawCommentText(CXCursor C) {
6289 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006290 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006291
6292 const Decl *D = getCursorDecl(C);
6293 ASTContext &Context = getCursorContext(C);
6294 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6295 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6296 StringRef();
6297
6298 // Don't duplicate the string because RawText points directly into source
6299 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006300 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006301}
6302
6303CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6304 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006305 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006306
6307 const Decl *D = getCursorDecl(C);
6308 const ASTContext &Context = getCursorContext(C);
6309 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6310
6311 if (RC) {
6312 StringRef BriefText = RC->getBriefText(Context);
6313
6314 // Don't duplicate the string because RawComment ensures that this memory
6315 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006316 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006317 }
6318
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006319 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006320}
6321
6322CXComment clang_Cursor_getParsedComment(CXCursor C) {
6323 if (!clang_isDeclaration(C.kind))
6324 return cxcomment::createCXComment(NULL, NULL);
6325
6326 const Decl *D = getCursorDecl(C);
6327 const ASTContext &Context = getCursorContext(C);
6328 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6329
6330 return cxcomment::createCXComment(FC, getCursorTU(C));
6331}
6332
6333CXModule clang_Cursor_getModule(CXCursor C) {
6334 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006335 if (const ImportDecl *ImportD =
6336 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006337 return ImportD->getImportedModule();
6338 }
6339
6340 return 0;
6341}
6342
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006343CXFile clang_Module_getASTFile(CXModule CXMod) {
6344 if (!CXMod)
6345 return 0;
6346 Module *Mod = static_cast<Module*>(CXMod);
6347 return const_cast<FileEntry *>(Mod->getASTFile());
6348}
6349
Guy Benyei11169dd2012-12-18 14:30:41 +00006350CXModule clang_Module_getParent(CXModule CXMod) {
6351 if (!CXMod)
6352 return 0;
6353 Module *Mod = static_cast<Module*>(CXMod);
6354 return Mod->Parent;
6355}
6356
6357CXString clang_Module_getName(CXModule CXMod) {
6358 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006359 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006360 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006361 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006362}
6363
6364CXString clang_Module_getFullName(CXModule CXMod) {
6365 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006366 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006367 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006368 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006369}
6370
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006371unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6372 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006373 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006374 LOG_BAD_TU(TU);
6375 return 0;
6376 }
6377 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006378 return 0;
6379 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006380 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6381 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6382 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006383}
6384
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006385CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6386 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006387 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006388 LOG_BAD_TU(TU);
6389 return 0;
6390 }
6391 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006392 return 0;
6393 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006394 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006395
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006396 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6397 if (Index < TopHeaders.size())
6398 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006399
6400 return 0;
6401}
6402
6403} // end: extern "C"
6404
6405//===----------------------------------------------------------------------===//
6406// C++ AST instrospection.
6407//===----------------------------------------------------------------------===//
6408
6409extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006410unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6411 if (!clang_isDeclaration(C.kind))
6412 return 0;
6413
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006414 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006415 const CXXMethodDecl *Method =
6416 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006417 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6418}
6419
Guy Benyei11169dd2012-12-18 14:30:41 +00006420unsigned clang_CXXMethod_isStatic(CXCursor C) {
6421 if (!clang_isDeclaration(C.kind))
6422 return 0;
6423
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006424 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006425 const CXXMethodDecl *Method =
6426 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006427 return (Method && Method->isStatic()) ? 1 : 0;
6428}
6429
6430unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6431 if (!clang_isDeclaration(C.kind))
6432 return 0;
6433
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006434 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006435 const CXXMethodDecl *Method =
6436 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006437 return (Method && Method->isVirtual()) ? 1 : 0;
6438}
6439} // end: extern "C"
6440
6441//===----------------------------------------------------------------------===//
6442// Attribute introspection.
6443//===----------------------------------------------------------------------===//
6444
6445extern "C" {
6446CXType clang_getIBOutletCollectionType(CXCursor C) {
6447 if (C.kind != CXCursor_IBOutletCollectionAttr)
6448 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6449
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006450 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006451 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6452
6453 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6454}
6455} // end: extern "C"
6456
6457//===----------------------------------------------------------------------===//
6458// Inspecting memory usage.
6459//===----------------------------------------------------------------------===//
6460
6461typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6462
6463static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6464 enum CXTUResourceUsageKind k,
6465 unsigned long amount) {
6466 CXTUResourceUsageEntry entry = { k, amount };
6467 entries.push_back(entry);
6468}
6469
6470extern "C" {
6471
6472const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6473 const char *str = "";
6474 switch (kind) {
6475 case CXTUResourceUsage_AST:
6476 str = "ASTContext: expressions, declarations, and types";
6477 break;
6478 case CXTUResourceUsage_Identifiers:
6479 str = "ASTContext: identifiers";
6480 break;
6481 case CXTUResourceUsage_Selectors:
6482 str = "ASTContext: selectors";
6483 break;
6484 case CXTUResourceUsage_GlobalCompletionResults:
6485 str = "Code completion: cached global results";
6486 break;
6487 case CXTUResourceUsage_SourceManagerContentCache:
6488 str = "SourceManager: content cache allocator";
6489 break;
6490 case CXTUResourceUsage_AST_SideTables:
6491 str = "ASTContext: side tables";
6492 break;
6493 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6494 str = "SourceManager: malloc'ed memory buffers";
6495 break;
6496 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6497 str = "SourceManager: mmap'ed memory buffers";
6498 break;
6499 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6500 str = "ExternalASTSource: malloc'ed memory buffers";
6501 break;
6502 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6503 str = "ExternalASTSource: mmap'ed memory buffers";
6504 break;
6505 case CXTUResourceUsage_Preprocessor:
6506 str = "Preprocessor: malloc'ed memory";
6507 break;
6508 case CXTUResourceUsage_PreprocessingRecord:
6509 str = "Preprocessor: PreprocessingRecord";
6510 break;
6511 case CXTUResourceUsage_SourceManager_DataStructures:
6512 str = "SourceManager: data structures and tables";
6513 break;
6514 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6515 str = "Preprocessor: header search tables";
6516 break;
6517 }
6518 return str;
6519}
6520
6521CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006522 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006523 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006524 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6525 return usage;
6526 }
6527
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006528 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006529 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6530 ASTContext &astContext = astUnit->getASTContext();
6531
6532 // How much memory is used by AST nodes and types?
6533 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6534 (unsigned long) astContext.getASTAllocatedMemory());
6535
6536 // How much memory is used by identifiers?
6537 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6538 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6539
6540 // How much memory is used for selectors?
6541 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6542 (unsigned long) astContext.Selectors.getTotalMemory());
6543
6544 // How much memory is used by ASTContext's side tables?
6545 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6546 (unsigned long) astContext.getSideTableAllocatedMemory());
6547
6548 // How much memory is used for caching global code completion results?
6549 unsigned long completionBytes = 0;
6550 if (GlobalCodeCompletionAllocator *completionAllocator =
6551 astUnit->getCachedCompletionAllocator().getPtr()) {
6552 completionBytes = completionAllocator->getTotalMemory();
6553 }
6554 createCXTUResourceUsageEntry(*entries,
6555 CXTUResourceUsage_GlobalCompletionResults,
6556 completionBytes);
6557
6558 // How much memory is being used by SourceManager's content cache?
6559 createCXTUResourceUsageEntry(*entries,
6560 CXTUResourceUsage_SourceManagerContentCache,
6561 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6562
6563 // How much memory is being used by the MemoryBuffer's in SourceManager?
6564 const SourceManager::MemoryBufferSizes &srcBufs =
6565 astUnit->getSourceManager().getMemoryBufferSizes();
6566
6567 createCXTUResourceUsageEntry(*entries,
6568 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6569 (unsigned long) srcBufs.malloc_bytes);
6570 createCXTUResourceUsageEntry(*entries,
6571 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6572 (unsigned long) srcBufs.mmap_bytes);
6573 createCXTUResourceUsageEntry(*entries,
6574 CXTUResourceUsage_SourceManager_DataStructures,
6575 (unsigned long) astContext.getSourceManager()
6576 .getDataStructureSizes());
6577
6578 // How much memory is being used by the ExternalASTSource?
6579 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6580 const ExternalASTSource::MemoryBufferSizes &sizes =
6581 esrc->getMemoryBufferSizes();
6582
6583 createCXTUResourceUsageEntry(*entries,
6584 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6585 (unsigned long) sizes.malloc_bytes);
6586 createCXTUResourceUsageEntry(*entries,
6587 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6588 (unsigned long) sizes.mmap_bytes);
6589 }
6590
6591 // How much memory is being used by the Preprocessor?
6592 Preprocessor &pp = astUnit->getPreprocessor();
6593 createCXTUResourceUsageEntry(*entries,
6594 CXTUResourceUsage_Preprocessor,
6595 pp.getTotalMemory());
6596
6597 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6598 createCXTUResourceUsageEntry(*entries,
6599 CXTUResourceUsage_PreprocessingRecord,
6600 pRec->getTotalMemory());
6601 }
6602
6603 createCXTUResourceUsageEntry(*entries,
6604 CXTUResourceUsage_Preprocessor_HeaderSearch,
6605 pp.getHeaderSearchInfo().getTotalMemory());
6606
6607 CXTUResourceUsage usage = { (void*) entries.get(),
6608 (unsigned) entries->size(),
6609 entries->size() ? &(*entries)[0] : 0 };
6610 entries.take();
6611 return usage;
6612}
6613
6614void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6615 if (usage.data)
6616 delete (MemUsageEntries*) usage.data;
6617}
6618
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006619CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6620 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006621 skipped->count = 0;
6622 skipped->ranges = 0;
6623
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006624 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006625 LOG_BAD_TU(TU);
6626 return skipped;
6627 }
6628
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006629 if (!file)
6630 return skipped;
6631
6632 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6633 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6634 if (!ppRec)
6635 return skipped;
6636
6637 ASTContext &Ctx = astUnit->getASTContext();
6638 SourceManager &sm = Ctx.getSourceManager();
6639 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6640 FileID wantedFileID = sm.translateFile(fileEntry);
6641
6642 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6643 std::vector<SourceRange> wantedRanges;
6644 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6645 i != ei; ++i) {
6646 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6647 wantedRanges.push_back(*i);
6648 }
6649
6650 skipped->count = wantedRanges.size();
6651 skipped->ranges = new CXSourceRange[skipped->count];
6652 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6653 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6654
6655 return skipped;
6656}
6657
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006658void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6659 if (ranges) {
6660 delete[] ranges->ranges;
6661 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006662 }
6663}
6664
Guy Benyei11169dd2012-12-18 14:30:41 +00006665} // end extern "C"
6666
6667void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6668 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6669 for (unsigned I = 0; I != Usage.numEntries; ++I)
6670 fprintf(stderr, " %s: %lu\n",
6671 clang_getTUResourceUsageName(Usage.entries[I].kind),
6672 Usage.entries[I].amount);
6673
6674 clang_disposeCXTUResourceUsage(Usage);
6675}
6676
6677//===----------------------------------------------------------------------===//
6678// Misc. utility functions.
6679//===----------------------------------------------------------------------===//
6680
6681/// Default to using an 8 MB stack size on "safety" threads.
6682static unsigned SafetyStackThreadSize = 8 << 20;
6683
6684namespace clang {
6685
6686bool RunSafely(llvm::CrashRecoveryContext &CRC,
6687 void (*Fn)(void*), void *UserData,
6688 unsigned Size) {
6689 if (!Size)
6690 Size = GetSafetyThreadStackSize();
6691 if (Size)
6692 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6693 return CRC.RunSafely(Fn, UserData);
6694}
6695
6696unsigned GetSafetyThreadStackSize() {
6697 return SafetyStackThreadSize;
6698}
6699
6700void SetSafetyThreadStackSize(unsigned Value) {
6701 SafetyStackThreadSize = Value;
6702}
6703
6704}
6705
6706void clang::setThreadBackgroundPriority() {
6707 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6708 return;
6709
6710 // FIXME: Move to llvm/Support and make it cross-platform.
6711#ifdef __APPLE__
6712 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6713#endif
6714}
6715
6716void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6717 if (!Unit)
6718 return;
6719
6720 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6721 DEnd = Unit->stored_diag_end();
6722 D != DEnd; ++D) {
6723 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6724 CXString Msg = clang_formatDiagnostic(&Diag,
6725 clang_defaultDiagnosticDisplayOptions());
6726 fprintf(stderr, "%s\n", clang_getCString(Msg));
6727 clang_disposeString(Msg);
6728 }
6729#ifdef LLVM_ON_WIN32
6730 // On Windows, force a flush, since there may be multiple copies of
6731 // stderr and stdout in the file system, all with different buffers
6732 // but writing to the same device.
6733 fflush(stderr);
6734#endif
6735}
6736
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006737MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6738 SourceLocation MacroDefLoc,
6739 CXTranslationUnit TU){
6740 if (MacroDefLoc.isInvalid() || !TU)
6741 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006742 if (!II.hadMacroDefinition())
6743 return 0;
6744
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006745 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006746 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006747 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006748 if (MD) {
6749 for (MacroDirective::DefInfo
6750 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6751 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6752 return Def.getMacroInfo();
6753 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006754 }
6755
6756 return 0;
6757}
6758
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006759const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6760 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006761 if (!MacroDef || !TU)
6762 return 0;
6763 const IdentifierInfo *II = MacroDef->getName();
6764 if (!II)
6765 return 0;
6766
6767 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6768}
6769
6770MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6771 const Token &Tok,
6772 CXTranslationUnit TU) {
6773 if (!MI || !TU)
6774 return 0;
6775 if (Tok.isNot(tok::raw_identifier))
6776 return 0;
6777
6778 if (MI->getNumTokens() == 0)
6779 return 0;
6780 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6781 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006782 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006783
6784 // Check that the token is inside the definition and not its argument list.
6785 SourceManager &SM = Unit->getSourceManager();
6786 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6787 return 0;
6788 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6789 return 0;
6790
6791 Preprocessor &PP = Unit->getPreprocessor();
6792 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6793 if (!PPRec)
6794 return 0;
6795
6796 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6797 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6798 if (!II.hadMacroDefinition())
6799 return 0;
6800
6801 // Check that the identifier is not one of the macro arguments.
6802 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6803 return 0;
6804
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006805 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6806 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006807 return 0;
6808
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006809 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006810}
6811
6812MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6813 SourceLocation Loc,
6814 CXTranslationUnit TU) {
6815 if (Loc.isInvalid() || !MI || !TU)
6816 return 0;
6817
6818 if (MI->getNumTokens() == 0)
6819 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006820 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006821 Preprocessor &PP = Unit->getPreprocessor();
6822 if (!PP.getPreprocessingRecord())
6823 return 0;
6824 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6825 Token Tok;
6826 if (PP.getRawToken(Loc, Tok))
6827 return 0;
6828
6829 return checkForMacroInMacroDefinition(MI, Tok, TU);
6830}
6831
Guy Benyei11169dd2012-12-18 14:30:41 +00006832extern "C" {
6833
6834CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006835 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006836}
6837
6838} // end: extern "C"
6839
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006840Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6841 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006842 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006843 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006844 if (Unit->isMainFileAST())
6845 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006846 return *this;
6847 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006848 } else {
6849 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006850 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006851 return *this;
6852}
6853
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006854Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6855 *this << FE->getName();
6856 return *this;
6857}
6858
6859Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6860 CXString cursorName = clang_getCursorDisplayName(cursor);
6861 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6862 clang_disposeString(cursorName);
6863 return *this;
6864}
6865
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006866Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6867 CXFile File;
6868 unsigned Line, Column;
6869 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6870 CXString FileName = clang_getFileName(File);
6871 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6872 clang_disposeString(FileName);
6873 return *this;
6874}
6875
6876Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6877 CXSourceLocation BLoc = clang_getRangeStart(range);
6878 CXSourceLocation ELoc = clang_getRangeEnd(range);
6879
6880 CXFile BFile;
6881 unsigned BLine, BColumn;
6882 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6883
6884 CXFile EFile;
6885 unsigned ELine, EColumn;
6886 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6887
6888 CXString BFileName = clang_getFileName(BFile);
6889 if (BFile == EFile) {
6890 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6891 BLine, BColumn, ELine, EColumn);
6892 } else {
6893 CXString EFileName = clang_getFileName(EFile);
6894 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6895 BLine, BColumn)
6896 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6897 ELine, EColumn);
6898 clang_disposeString(EFileName);
6899 }
6900 clang_disposeString(BFileName);
6901 return *this;
6902}
6903
6904Logger &cxindex::Logger::operator<<(CXString Str) {
6905 *this << clang_getCString(Str);
6906 return *this;
6907}
6908
6909Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6910 LogOS << Fmt;
6911 return *this;
6912}
6913
6914cxindex::Logger::~Logger() {
6915 LogOS.flush();
6916
6917 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6918
6919 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6920
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006921 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006922 OS << "[libclang:" << Name << ':';
6923
6924 // FIXME: Portability.
6925#if HAVE_PTHREAD_H && __APPLE__
6926 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6927 OS << tid << ':';
6928#endif
6929
6930 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6931 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6932 OS << Msg.str() << '\n';
6933
6934 if (Trace) {
6935 llvm::sys::PrintStackTrace(stderr);
6936 OS << "--------------------------------------------------\n";
6937 }
6938}