blob: 67bcff963fff6ce8ed9d6007caca2b6bc08ae53c [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXComment.h"
19#include "CXCursor.h"
20#include "CXSourceLocation.h"
21#include "CXString.h"
22#include "CXTranslationUnit.h"
23#include "CXType.h"
24#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000025#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000030#include "clang/Basic/Version.h"
31#include "clang/Frontend/ASTUnit.h"
32#include "clang/Frontend/CompilerInstance.h"
33#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000034#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000035#include "clang/Lex/HeaderSearch.h"
36#include "clang/Lex/Lexer.h"
37#include "clang/Lex/PreprocessingRecord.h"
38#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000039#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000040#include "llvm/ADT/Optional.h"
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/StringSwitch.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000043#include "llvm/Config/config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000044#include "llvm/Support/Compiler.h"
45#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000046#include "llvm/Support/Format.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/MemoryBuffer.h"
48#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000049#include "llvm/Support/Program.h"
50#include "llvm/Support/SaveAndRestore.h"
51#include "llvm/Support/Signals.h"
52#include "llvm/Support/Threading.h"
53#include "llvm/Support/Timer.h"
54#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000055
56#if HAVE_PTHREAD_H
57#include <pthread.h>
58#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000059
60using namespace clang;
61using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000062using namespace clang::cxtu;
63using namespace clang::cxindex;
64
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000065CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
66 if (!AU)
Guy Benyei11169dd2012-12-18 14:30:41 +000067 return 0;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000068 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000069 CXTranslationUnit D = new CXTranslationUnitImpl();
70 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000071 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000072 D->StringPool = new cxstring::CXStringPool();
Guy Benyei11169dd2012-12-18 14:30:41 +000073 D->Diagnostics = 0;
74 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Dmitri Gribenko9e605112013-11-13 22:16:51 +000075 D->CommentToXML = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +000076 return D;
77}
78
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000079bool cxtu::isASTReadError(ASTUnit *AU) {
80 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
81 DEnd = AU->stored_diag_end();
82 D != DEnd; ++D) {
83 if (D->getLevel() >= DiagnosticsEngine::Error &&
84 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
85 diag::DiagCat_AST_Deserialization_Issue)
86 return true;
87 }
88 return false;
89}
90
Guy Benyei11169dd2012-12-18 14:30:41 +000091cxtu::CXTUOwner::~CXTUOwner() {
92 if (TU)
93 clang_disposeTranslationUnit(TU);
94}
95
96/// \brief Compare two source ranges to determine their relative position in
97/// the translation unit.
98static RangeComparisonResult RangeCompare(SourceManager &SM,
99 SourceRange R1,
100 SourceRange R2) {
101 assert(R1.isValid() && "First range is invalid?");
102 assert(R2.isValid() && "Second range is invalid?");
103 if (R1.getEnd() != R2.getBegin() &&
104 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
105 return RangeBefore;
106 if (R2.getEnd() != R1.getBegin() &&
107 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
108 return RangeAfter;
109 return RangeOverlap;
110}
111
112/// \brief Determine if a source location falls within, before, or after a
113/// a given source range.
114static RangeComparisonResult LocationCompare(SourceManager &SM,
115 SourceLocation L, SourceRange R) {
116 assert(R.isValid() && "First range is invalid?");
117 assert(L.isValid() && "Second range is invalid?");
118 if (L == R.getBegin() || L == R.getEnd())
119 return RangeOverlap;
120 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
121 return RangeBefore;
122 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
123 return RangeAfter;
124 return RangeOverlap;
125}
126
127/// \brief Translate a Clang source range into a CIndex source range.
128///
129/// Clang internally represents ranges where the end location points to the
130/// start of the token at the end. However, for external clients it is more
131/// useful to have a CXSourceRange be a proper half-open interval. This routine
132/// does the appropriate translation.
133CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
134 const LangOptions &LangOpts,
135 const CharSourceRange &R) {
136 // We want the last character in this location, so we will adjust the
137 // location accordingly.
138 SourceLocation EndLoc = R.getEnd();
139 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
140 EndLoc = SM.getExpansionRange(EndLoc).second;
141 if (R.isTokenRange() && !EndLoc.isInvalid()) {
142 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
143 SM, LangOpts);
144 EndLoc = EndLoc.getLocWithOffset(Length);
145 }
146
Bill Wendlingeade3622013-01-23 08:25:41 +0000147 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000148 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000149 R.getBegin().getRawEncoding(),
150 EndLoc.getRawEncoding()
151 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000152 return Result;
153}
154
155//===----------------------------------------------------------------------===//
156// Cursor visitor.
157//===----------------------------------------------------------------------===//
158
159static SourceRange getRawCursorExtent(CXCursor C);
160static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
161
162
163RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
164 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
165}
166
167/// \brief Visit the given cursor and, if requested by the visitor,
168/// its children.
169///
170/// \param Cursor the cursor to visit.
171///
172/// \param CheckedRegionOfInterest if true, then the caller already checked
173/// that this cursor is within the region of interest.
174///
175/// \returns true if the visitation should be aborted, false if it
176/// should continue.
177bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
178 if (clang_isInvalid(Cursor.kind))
179 return false;
180
181 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000182 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000183 if (!D) {
184 assert(0 && "Invalid declaration cursor");
185 return true; // abort.
186 }
187
188 // Ignore implicit declarations, unless it's an objc method because
189 // currently we should report implicit methods for properties when indexing.
190 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
191 return false;
192 }
193
194 // If we have a range of interest, and this cursor doesn't intersect with it,
195 // we're done.
196 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
197 SourceRange Range = getRawCursorExtent(Cursor);
198 if (Range.isInvalid() || CompareRegionOfInterest(Range))
199 return false;
200 }
201
202 switch (Visitor(Cursor, Parent, ClientData)) {
203 case CXChildVisit_Break:
204 return true;
205
206 case CXChildVisit_Continue:
207 return false;
208
209 case CXChildVisit_Recurse: {
210 bool ret = VisitChildren(Cursor);
211 if (PostChildrenVisitor)
212 if (PostChildrenVisitor(Cursor, ClientData))
213 return true;
214 return ret;
215 }
216 }
217
218 llvm_unreachable("Invalid CXChildVisitResult!");
219}
220
221static bool visitPreprocessedEntitiesInRange(SourceRange R,
222 PreprocessingRecord &PPRec,
223 CursorVisitor &Visitor) {
224 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
225 FileID FID;
226
227 if (!Visitor.shouldVisitIncludedEntities()) {
228 // If the begin/end of the range lie in the same FileID, do the optimization
229 // where we skip preprocessed entities that do not come from the same FileID.
230 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
231 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
232 FID = FileID();
233 }
234
235 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
236 Entities = PPRec.getPreprocessedEntitiesInRange(R);
237 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
238 PPRec, FID);
239}
240
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000241bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000242 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000243 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000244
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000245 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 SourceManager &SM = Unit->getSourceManager();
247
248 std::pair<FileID, unsigned>
249 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
250 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
251
252 if (End.first != Begin.first) {
253 // If the end does not reside in the same file, try to recover by
254 // picking the end of the file of begin location.
255 End.first = Begin.first;
256 End.second = SM.getFileIDSize(Begin.first);
257 }
258
259 assert(Begin.first == End.first);
260 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000261 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000262
263 FileID File = Begin.first;
264 unsigned Offset = Begin.second;
265 unsigned Length = End.second - Begin.second;
266
267 if (!VisitDeclsOnly && !VisitPreprocessorLast)
268 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000271 if (visitDeclsFromFileRegion(File, Offset, Length))
272 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000273
274 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000275 return visitPreprocessedEntitiesInRegion();
276
277 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000278}
279
280static bool isInLexicalContext(Decl *D, DeclContext *DC) {
281 if (!DC)
282 return false;
283
284 for (DeclContext *DeclDC = D->getLexicalDeclContext();
285 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
286 if (DeclDC == DC)
287 return true;
288 }
289 return false;
290}
291
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000292bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000293 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000294 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000295 SourceManager &SM = Unit->getSourceManager();
296 SourceRange Range = RegionOfInterest;
297
298 SmallVector<Decl *, 16> Decls;
299 Unit->findFileRegionDecls(File, Offset, Length, Decls);
300
301 // If we didn't find any file level decls for the file, try looking at the
302 // file that it was included from.
303 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
304 bool Invalid = false;
305 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
306 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000307 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000308
309 SourceLocation Outer;
310 if (SLEntry.isFile())
311 Outer = SLEntry.getFile().getIncludeLoc();
312 else
313 Outer = SLEntry.getExpansion().getExpansionLocStart();
314 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000317 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000318 Length = 0;
319 Unit->findFileRegionDecls(File, Offset, Length, Decls);
320 }
321
322 assert(!Decls.empty());
323
324 bool VisitedAtLeastOnce = false;
325 DeclContext *CurDC = 0;
Craig Topper2341c0d2013-07-04 03:08:24 +0000326 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
327 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000328 Decl *D = *DIt;
329 if (D->getSourceRange().isInvalid())
330 continue;
331
332 if (isInLexicalContext(D, CurDC))
333 continue;
334
335 CurDC = dyn_cast<DeclContext>(D);
336
337 if (TagDecl *TD = dyn_cast<TagDecl>(D))
338 if (!TD->isFreeStanding())
339 continue;
340
341 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
342 if (CompRes == RangeBefore)
343 continue;
344 if (CompRes == RangeAfter)
345 break;
346
347 assert(CompRes == RangeOverlap);
348 VisitedAtLeastOnce = true;
349
350 if (isa<ObjCContainerDecl>(D)) {
351 FileDI_current = &DIt;
352 FileDE_current = DE;
353 } else {
354 FileDI_current = 0;
355 }
356
357 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000358 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000359 }
360
361 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000362 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363
364 // No Decls overlapped with the range. Move up the lexical context until there
365 // is a context that contains the range or we reach the translation unit
366 // level.
367 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
368 : (*(DIt-1))->getLexicalDeclContext();
369
370 while (DC && !DC->isTranslationUnit()) {
371 Decl *D = cast<Decl>(DC);
372 SourceRange CurDeclRange = D->getSourceRange();
373 if (CurDeclRange.isInvalid())
374 break;
375
376 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000377 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
378 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000379 }
380
381 DC = D->getLexicalDeclContext();
382 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000383
384 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000385}
386
387bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
388 if (!AU->getPreprocessor().getPreprocessingRecord())
389 return false;
390
391 PreprocessingRecord &PPRec
392 = *AU->getPreprocessor().getPreprocessingRecord();
393 SourceManager &SM = AU->getSourceManager();
394
395 if (RegionOfInterest.isValid()) {
396 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
397 SourceLocation B = MappedRange.getBegin();
398 SourceLocation E = MappedRange.getEnd();
399
400 if (AU->isInPreambleFileID(B)) {
401 if (SM.isLoadedSourceLocation(E))
402 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
403 PPRec, *this);
404
405 // Beginning of range lies in the preamble but it also extends beyond
406 // it into the main file. Split the range into 2 parts, one covering
407 // the preamble and another covering the main file. This allows subsequent
408 // calls to visitPreprocessedEntitiesInRange to accept a source range that
409 // lies in the same FileID, allowing it to skip preprocessed entities that
410 // do not come from the same FileID.
411 bool breaked =
412 visitPreprocessedEntitiesInRange(
413 SourceRange(B, AU->getEndOfPreambleFileID()),
414 PPRec, *this);
415 if (breaked) return true;
416 return visitPreprocessedEntitiesInRange(
417 SourceRange(AU->getStartOfMainFileID(), E),
418 PPRec, *this);
419 }
420
421 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
422 }
423
424 bool OnlyLocalDecls
425 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
426
427 if (OnlyLocalDecls)
428 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
429 PPRec);
430
431 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
432}
433
434template<typename InputIterator>
435bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
436 InputIterator Last,
437 PreprocessingRecord &PPRec,
438 FileID FID) {
439 for (; First != Last; ++First) {
440 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
441 continue;
442
443 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000444 if (!PPE)
445 continue;
446
Guy Benyei11169dd2012-12-18 14:30:41 +0000447 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
448 if (Visit(MakeMacroExpansionCursor(ME, TU)))
449 return true;
450
451 continue;
452 }
453
454 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
455 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
456 return true;
457
458 continue;
459 }
460
461 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
462 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
463 return true;
464
465 continue;
466 }
467 }
468
469 return false;
470}
471
472/// \brief Visit the children of the given cursor.
473///
474/// \returns true if the visitation should be aborted, false if it
475/// should continue.
476bool CursorVisitor::VisitChildren(CXCursor Cursor) {
477 if (clang_isReference(Cursor.kind) &&
478 Cursor.kind != CXCursor_CXXBaseSpecifier) {
479 // By definition, references have no children.
480 return false;
481 }
482
483 // Set the Parent field to Cursor, then back to its old value once we're
484 // done.
485 SetParentRAII SetParent(Parent, StmtParent, Cursor);
486
487 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000488 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000489 if (!D)
490 return false;
491
492 return VisitAttributes(D) || Visit(D);
493 }
494
495 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000496 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 return Visit(S);
498
499 return false;
500 }
501
502 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000503 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000504 return Visit(E);
505
506 return false;
507 }
508
509 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000510 CXTranslationUnit TU = getCursorTU(Cursor);
511 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000512
513 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
514 for (unsigned I = 0; I != 2; ++I) {
515 if (VisitOrder[I]) {
516 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
517 RegionOfInterest.isInvalid()) {
518 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
519 TLEnd = CXXUnit->top_level_end();
520 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000521 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000522 return true;
523 }
524 } else if (VisitDeclContext(
525 CXXUnit->getASTContext().getTranslationUnitDecl()))
526 return true;
527 continue;
528 }
529
530 // Walk the preprocessing record.
531 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
532 visitPreprocessedEntitiesInRegion();
533 }
534
535 return false;
536 }
537
538 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000539 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000540 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
541 return Visit(BaseTSInfo->getTypeLoc());
542 }
543 }
544 }
545
546 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000547 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000549 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000550 return Visit(cxcursor::MakeCursorObjCClassRef(
551 ObjT->getInterface(),
552 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000553 }
554
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000555 // If pointing inside a macro definition, check if the token is an identifier
556 // that was ever defined as a macro. In such a case, create a "pseudo" macro
557 // expansion cursor for that token.
558 SourceLocation BeginLoc = RegionOfInterest.getBegin();
559 if (Cursor.kind == CXCursor_MacroDefinition &&
560 BeginLoc == RegionOfInterest.getEnd()) {
561 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000562 const MacroInfo *MI =
563 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000564 if (MacroDefinition *MacroDef =
565 checkForMacroInMacroDefinition(MI, Loc, TU))
566 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
567 }
568
Guy Benyei11169dd2012-12-18 14:30:41 +0000569 // Nothing to visit at the moment.
570 return false;
571}
572
573bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
574 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
575 if (Visit(TSInfo->getTypeLoc()))
576 return true;
577
578 if (Stmt *Body = B->getBody())
579 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
580
581 return false;
582}
583
Ted Kremenek03325582013-02-21 01:29:01 +0000584Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000585 if (RegionOfInterest.isValid()) {
586 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
587 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000588 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000589
590 switch (CompareRegionOfInterest(Range)) {
591 case RangeBefore:
592 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000593 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000594
595 case RangeAfter:
596 // This declaration comes after the region of interest; we're done.
597 return false;
598
599 case RangeOverlap:
600 // This declaration overlaps the region of interest; visit it.
601 break;
602 }
603 }
604 return true;
605}
606
607bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
608 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
609
610 // FIXME: Eventually remove. This part of a hack to support proper
611 // iteration over all Decls contained lexically within an ObjC container.
612 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
613 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
614
615 for ( ; I != E; ++I) {
616 Decl *D = *I;
617 if (D->getLexicalDeclContext() != DC)
618 continue;
619 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
620
621 // Ignore synthesized ivars here, otherwise if we have something like:
622 // @synthesize prop = _prop;
623 // and '_prop' is not declared, we will encounter a '_prop' ivar before
624 // encountering the 'prop' synthesize declaration and we will think that
625 // we passed the region-of-interest.
626 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
627 if (ivarD->getSynthesize())
628 continue;
629 }
630
631 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
632 // declarations is a mismatch with the compiler semantics.
633 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
634 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
635 if (!ID->isThisDeclarationADefinition())
636 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
637
638 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
639 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
640 if (!PD->isThisDeclarationADefinition())
641 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
642 }
643
Ted Kremenek03325582013-02-21 01:29:01 +0000644 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000645 if (!V.hasValue())
646 continue;
647 if (!V.getValue())
648 return false;
649 if (Visit(Cursor, true))
650 return true;
651 }
652 return false;
653}
654
655bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
656 llvm_unreachable("Translation units are visited directly by Visit()");
657}
658
659bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
660 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
661 return Visit(TSInfo->getTypeLoc());
662
663 return false;
664}
665
666bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
667 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
668 return Visit(TSInfo->getTypeLoc());
669
670 return false;
671}
672
673bool CursorVisitor::VisitTagDecl(TagDecl *D) {
674 return VisitDeclContext(D);
675}
676
677bool CursorVisitor::VisitClassTemplateSpecializationDecl(
678 ClassTemplateSpecializationDecl *D) {
679 bool ShouldVisitBody = false;
680 switch (D->getSpecializationKind()) {
681 case TSK_Undeclared:
682 case TSK_ImplicitInstantiation:
683 // Nothing to visit
684 return false;
685
686 case TSK_ExplicitInstantiationDeclaration:
687 case TSK_ExplicitInstantiationDefinition:
688 break;
689
690 case TSK_ExplicitSpecialization:
691 ShouldVisitBody = true;
692 break;
693 }
694
695 // Visit the template arguments used in the specialization.
696 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
697 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000698 if (TemplateSpecializationTypeLoc TSTLoc =
699 TL.getAs<TemplateSpecializationTypeLoc>()) {
700 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
701 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000702 return true;
703 }
704 }
705
706 if (ShouldVisitBody && VisitCXXRecordDecl(D))
707 return true;
708
709 return false;
710}
711
712bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
713 ClassTemplatePartialSpecializationDecl *D) {
714 // FIXME: Visit the "outer" template parameter lists on the TagDecl
715 // before visiting these template parameters.
716 if (VisitTemplateParameters(D->getTemplateParameters()))
717 return true;
718
719 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000720 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
721 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
722 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000723 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
724 return true;
725
726 return VisitCXXRecordDecl(D);
727}
728
729bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
730 // Visit the default argument.
731 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
732 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
733 if (Visit(DefArg->getTypeLoc()))
734 return true;
735
736 return false;
737}
738
739bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
740 if (Expr *Init = D->getInitExpr())
741 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
742 return false;
743}
744
745bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000746 unsigned NumParamList = DD->getNumTemplateParameterLists();
747 for (unsigned i = 0; i < NumParamList; i++) {
748 TemplateParameterList* Params = DD->getTemplateParameterList(i);
749 if (VisitTemplateParameters(Params))
750 return true;
751 }
752
Guy Benyei11169dd2012-12-18 14:30:41 +0000753 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
754 if (Visit(TSInfo->getTypeLoc()))
755 return true;
756
757 // Visit the nested-name-specifier, if present.
758 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
759 if (VisitNestedNameSpecifierLoc(QualifierLoc))
760 return true;
761
762 return false;
763}
764
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000765/// \brief Compare two base or member initializers based on their source order.
766static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
767 CXXCtorInitializer *const *Y) {
768 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
769}
770
Guy Benyei11169dd2012-12-18 14:30:41 +0000771bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000772 unsigned NumParamList = ND->getNumTemplateParameterLists();
773 for (unsigned i = 0; i < NumParamList; i++) {
774 TemplateParameterList* Params = ND->getTemplateParameterList(i);
775 if (VisitTemplateParameters(Params))
776 return true;
777 }
778
Guy Benyei11169dd2012-12-18 14:30:41 +0000779 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
780 // Visit the function declaration's syntactic components in the order
781 // written. This requires a bit of work.
782 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000783 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000784
785 // If we have a function declared directly (without the use of a typedef),
786 // visit just the return type. Otherwise, just visit the function's type
787 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000788 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000789 (!FTL && Visit(TL)))
790 return true;
791
792 // Visit the nested-name-specifier, if present.
793 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
794 if (VisitNestedNameSpecifierLoc(QualifierLoc))
795 return true;
796
797 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000798 if (!isa<CXXDestructorDecl>(ND))
799 if (VisitDeclarationNameInfo(ND->getNameInfo()))
800 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000801
802 // FIXME: Visit explicitly-specified template arguments!
803
804 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000805 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000806 return true;
807
Bill Wendling44426052012-12-20 19:22:21 +0000808 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000809 }
810
811 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
812 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
813 // Find the initializers that were written in the source.
814 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000815 for (auto *I : Constructor->inits()) {
816 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000817 continue;
818
Aaron Ballman0ad78302014-03-13 17:34:31 +0000819 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000820 }
821
822 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000823 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
824 &CompareCXXCtorInitializers);
825
Guy Benyei11169dd2012-12-18 14:30:41 +0000826 // Visit the initializers in source order
827 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
828 CXXCtorInitializer *Init = WrittenInits[I];
829 if (Init->isAnyMemberInitializer()) {
830 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
831 Init->getMemberLocation(), TU)))
832 return true;
833 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
834 if (Visit(TInfo->getTypeLoc()))
835 return true;
836 }
837
838 // Visit the initializer value.
839 if (Expr *Initializer = Init->getInit())
840 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
841 return true;
842 }
843 }
844
845 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
846 return true;
847 }
848
849 return false;
850}
851
852bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
853 if (VisitDeclaratorDecl(D))
854 return true;
855
856 if (Expr *BitWidth = D->getBitWidth())
857 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
858
859 return false;
860}
861
862bool CursorVisitor::VisitVarDecl(VarDecl *D) {
863 if (VisitDeclaratorDecl(D))
864 return true;
865
866 if (Expr *Init = D->getInit())
867 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
868
869 return false;
870}
871
872bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
873 if (VisitDeclaratorDecl(D))
874 return true;
875
876 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
877 if (Expr *DefArg = D->getDefaultArgument())
878 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
879
880 return false;
881}
882
883bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
884 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
885 // before visiting these template parameters.
886 if (VisitTemplateParameters(D->getTemplateParameters()))
887 return true;
888
889 return VisitFunctionDecl(D->getTemplatedDecl());
890}
891
892bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
893 // FIXME: Visit the "outer" template parameter lists on the TagDecl
894 // before visiting these template parameters.
895 if (VisitTemplateParameters(D->getTemplateParameters()))
896 return true;
897
898 return VisitCXXRecordDecl(D->getTemplatedDecl());
899}
900
901bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
902 if (VisitTemplateParameters(D->getTemplateParameters()))
903 return true;
904
905 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
906 VisitTemplateArgumentLoc(D->getDefaultArgument()))
907 return true;
908
909 return false;
910}
911
912bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000913 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000914 if (Visit(TSInfo->getTypeLoc()))
915 return true;
916
Aaron Ballman43b68be2014-03-07 17:50:17 +0000917 for (const auto *P : ND->params()) {
918 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000919 return true;
920 }
921
922 if (ND->isThisDeclarationADefinition() &&
923 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
924 return true;
925
926 return false;
927}
928
929template <typename DeclIt>
930static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
931 SourceManager &SM, SourceLocation EndLoc,
932 SmallVectorImpl<Decl *> &Decls) {
933 DeclIt next = *DI_current;
934 while (++next != DE_current) {
935 Decl *D_next = *next;
936 if (!D_next)
937 break;
938 SourceLocation L = D_next->getLocStart();
939 if (!L.isValid())
940 break;
941 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
942 *DI_current = next;
943 Decls.push_back(D_next);
944 continue;
945 }
946 break;
947 }
948}
949
Guy Benyei11169dd2012-12-18 14:30:41 +0000950bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
951 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
952 // an @implementation can lexically contain Decls that are not properly
953 // nested in the AST. When we identify such cases, we need to retrofit
954 // this nesting here.
955 if (!DI_current && !FileDI_current)
956 return VisitDeclContext(D);
957
958 // Scan the Decls that immediately come after the container
959 // in the current DeclContext. If any fall within the
960 // container's lexical region, stash them into a vector
961 // for later processing.
962 SmallVector<Decl *, 24> DeclsInContainer;
963 SourceLocation EndLoc = D->getSourceRange().getEnd();
964 SourceManager &SM = AU->getSourceManager();
965 if (EndLoc.isValid()) {
966 if (DI_current) {
967 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
968 DeclsInContainer);
969 } else {
970 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
971 DeclsInContainer);
972 }
973 }
974
975 // The common case.
976 if (DeclsInContainer.empty())
977 return VisitDeclContext(D);
978
979 // Get all the Decls in the DeclContext, and sort them with the
980 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000981 for (auto *SubDecl : D->decls()) {
982 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
983 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000984 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000985 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000986 }
987
988 // Now sort the Decls so that they appear in lexical order.
989 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000990 [&SM](Decl *A, Decl *B) {
991 SourceLocation L_A = A->getLocStart();
992 SourceLocation L_B = B->getLocStart();
993 assert(L_A.isValid() && L_B.isValid());
994 return SM.isBeforeInTranslationUnit(L_A, L_B);
995 });
Guy Benyei11169dd2012-12-18 14:30:41 +0000996
997 // Now visit the decls.
998 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
999 E = DeclsInContainer.end(); I != E; ++I) {
1000 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001001 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001002 if (!V.hasValue())
1003 continue;
1004 if (!V.getValue())
1005 return false;
1006 if (Visit(Cursor, true))
1007 return true;
1008 }
1009 return false;
1010}
1011
1012bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1013 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1014 TU)))
1015 return true;
1016
1017 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1018 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1019 E = ND->protocol_end(); I != E; ++I, ++PL)
1020 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1021 return true;
1022
1023 return VisitObjCContainerDecl(ND);
1024}
1025
1026bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1027 if (!PID->isThisDeclarationADefinition())
1028 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1029
1030 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1031 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1032 E = PID->protocol_end(); I != E; ++I, ++PL)
1033 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1034 return true;
1035
1036 return VisitObjCContainerDecl(PID);
1037}
1038
1039bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1040 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1041 return true;
1042
1043 // FIXME: This implements a workaround with @property declarations also being
1044 // installed in the DeclContext for the @interface. Eventually this code
1045 // should be removed.
1046 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1047 if (!CDecl || !CDecl->IsClassExtension())
1048 return false;
1049
1050 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1051 if (!ID)
1052 return false;
1053
1054 IdentifierInfo *PropertyId = PD->getIdentifier();
1055 ObjCPropertyDecl *prevDecl =
1056 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1057
1058 if (!prevDecl)
1059 return false;
1060
1061 // Visit synthesized methods since they will be skipped when visiting
1062 // the @interface.
1063 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1064 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1065 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1066 return true;
1067
1068 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1069 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1070 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1071 return true;
1072
1073 return false;
1074}
1075
1076bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1077 if (!D->isThisDeclarationADefinition()) {
1078 // Forward declaration is treated like a reference.
1079 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1080 }
1081
1082 // Issue callbacks for super class.
1083 if (D->getSuperClass() &&
1084 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1085 D->getSuperClassLoc(),
1086 TU)))
1087 return true;
1088
1089 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1090 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1091 E = D->protocol_end(); I != E; ++I, ++PL)
1092 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1093 return true;
1094
1095 return VisitObjCContainerDecl(D);
1096}
1097
1098bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1099 return VisitObjCContainerDecl(D);
1100}
1101
1102bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1103 // 'ID' could be null when dealing with invalid code.
1104 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1105 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1106 return true;
1107
1108 return VisitObjCImplDecl(D);
1109}
1110
1111bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1112#if 0
1113 // Issue callbacks for super class.
1114 // FIXME: No source location information!
1115 if (D->getSuperClass() &&
1116 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1117 D->getSuperClassLoc(),
1118 TU)))
1119 return true;
1120#endif
1121
1122 return VisitObjCImplDecl(D);
1123}
1124
1125bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1126 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1127 if (PD->isIvarNameSpecified())
1128 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1129
1130 return false;
1131}
1132
1133bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1134 return VisitDeclContext(D);
1135}
1136
1137bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1138 // Visit nested-name-specifier.
1139 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1140 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1141 return true;
1142
1143 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1144 D->getTargetNameLoc(), TU));
1145}
1146
1147bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1148 // Visit nested-name-specifier.
1149 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1150 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1151 return true;
1152 }
1153
1154 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1155 return true;
1156
1157 return VisitDeclarationNameInfo(D->getNameInfo());
1158}
1159
1160bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1161 // Visit nested-name-specifier.
1162 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1163 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1164 return true;
1165
1166 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1167 D->getIdentLocation(), TU));
1168}
1169
1170bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1171 // Visit nested-name-specifier.
1172 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1173 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1174 return true;
1175 }
1176
1177 return VisitDeclarationNameInfo(D->getNameInfo());
1178}
1179
1180bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1181 UnresolvedUsingTypenameDecl *D) {
1182 // Visit nested-name-specifier.
1183 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1184 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1185 return true;
1186
1187 return false;
1188}
1189
1190bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1191 switch (Name.getName().getNameKind()) {
1192 case clang::DeclarationName::Identifier:
1193 case clang::DeclarationName::CXXLiteralOperatorName:
1194 case clang::DeclarationName::CXXOperatorName:
1195 case clang::DeclarationName::CXXUsingDirective:
1196 return false;
1197
1198 case clang::DeclarationName::CXXConstructorName:
1199 case clang::DeclarationName::CXXDestructorName:
1200 case clang::DeclarationName::CXXConversionFunctionName:
1201 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1202 return Visit(TSInfo->getTypeLoc());
1203 return false;
1204
1205 case clang::DeclarationName::ObjCZeroArgSelector:
1206 case clang::DeclarationName::ObjCOneArgSelector:
1207 case clang::DeclarationName::ObjCMultiArgSelector:
1208 // FIXME: Per-identifier location info?
1209 return false;
1210 }
1211
1212 llvm_unreachable("Invalid DeclarationName::Kind!");
1213}
1214
1215bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1216 SourceRange Range) {
1217 // FIXME: This whole routine is a hack to work around the lack of proper
1218 // source information in nested-name-specifiers (PR5791). Since we do have
1219 // a beginning source location, we can visit the first component of the
1220 // nested-name-specifier, if it's a single-token component.
1221 if (!NNS)
1222 return false;
1223
1224 // Get the first component in the nested-name-specifier.
1225 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1226 NNS = Prefix;
1227
1228 switch (NNS->getKind()) {
1229 case NestedNameSpecifier::Namespace:
1230 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1231 TU));
1232
1233 case NestedNameSpecifier::NamespaceAlias:
1234 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1235 Range.getBegin(), TU));
1236
1237 case NestedNameSpecifier::TypeSpec: {
1238 // If the type has a form where we know that the beginning of the source
1239 // range matches up with a reference cursor. Visit the appropriate reference
1240 // cursor.
1241 const Type *T = NNS->getAsType();
1242 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1243 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1244 if (const TagType *Tag = dyn_cast<TagType>(T))
1245 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1246 if (const TemplateSpecializationType *TST
1247 = dyn_cast<TemplateSpecializationType>(T))
1248 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1249 break;
1250 }
1251
1252 case NestedNameSpecifier::TypeSpecWithTemplate:
1253 case NestedNameSpecifier::Global:
1254 case NestedNameSpecifier::Identifier:
1255 break;
1256 }
1257
1258 return false;
1259}
1260
1261bool
1262CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1263 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1264 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1265 Qualifiers.push_back(Qualifier);
1266
1267 while (!Qualifiers.empty()) {
1268 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1269 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1270 switch (NNS->getKind()) {
1271 case NestedNameSpecifier::Namespace:
1272 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1273 Q.getLocalBeginLoc(),
1274 TU)))
1275 return true;
1276
1277 break;
1278
1279 case NestedNameSpecifier::NamespaceAlias:
1280 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1281 Q.getLocalBeginLoc(),
1282 TU)))
1283 return true;
1284
1285 break;
1286
1287 case NestedNameSpecifier::TypeSpec:
1288 case NestedNameSpecifier::TypeSpecWithTemplate:
1289 if (Visit(Q.getTypeLoc()))
1290 return true;
1291
1292 break;
1293
1294 case NestedNameSpecifier::Global:
1295 case NestedNameSpecifier::Identifier:
1296 break;
1297 }
1298 }
1299
1300 return false;
1301}
1302
1303bool CursorVisitor::VisitTemplateParameters(
1304 const TemplateParameterList *Params) {
1305 if (!Params)
1306 return false;
1307
1308 for (TemplateParameterList::const_iterator P = Params->begin(),
1309 PEnd = Params->end();
1310 P != PEnd; ++P) {
1311 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1312 return true;
1313 }
1314
1315 return false;
1316}
1317
1318bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1319 switch (Name.getKind()) {
1320 case TemplateName::Template:
1321 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1322
1323 case TemplateName::OverloadedTemplate:
1324 // Visit the overloaded template set.
1325 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1326 return true;
1327
1328 return false;
1329
1330 case TemplateName::DependentTemplate:
1331 // FIXME: Visit nested-name-specifier.
1332 return false;
1333
1334 case TemplateName::QualifiedTemplate:
1335 // FIXME: Visit nested-name-specifier.
1336 return Visit(MakeCursorTemplateRef(
1337 Name.getAsQualifiedTemplateName()->getDecl(),
1338 Loc, TU));
1339
1340 case TemplateName::SubstTemplateTemplateParm:
1341 return Visit(MakeCursorTemplateRef(
1342 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1343 Loc, TU));
1344
1345 case TemplateName::SubstTemplateTemplateParmPack:
1346 return Visit(MakeCursorTemplateRef(
1347 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1348 Loc, TU));
1349 }
1350
1351 llvm_unreachable("Invalid TemplateName::Kind!");
1352}
1353
1354bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1355 switch (TAL.getArgument().getKind()) {
1356 case TemplateArgument::Null:
1357 case TemplateArgument::Integral:
1358 case TemplateArgument::Pack:
1359 return false;
1360
1361 case TemplateArgument::Type:
1362 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1363 return Visit(TSInfo->getTypeLoc());
1364 return false;
1365
1366 case TemplateArgument::Declaration:
1367 if (Expr *E = TAL.getSourceDeclExpression())
1368 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1369 return false;
1370
1371 case TemplateArgument::NullPtr:
1372 if (Expr *E = TAL.getSourceNullPtrExpression())
1373 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1374 return false;
1375
1376 case TemplateArgument::Expression:
1377 if (Expr *E = TAL.getSourceExpression())
1378 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1379 return false;
1380
1381 case TemplateArgument::Template:
1382 case TemplateArgument::TemplateExpansion:
1383 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1384 return true;
1385
1386 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1387 TAL.getTemplateNameLoc());
1388 }
1389
1390 llvm_unreachable("Invalid TemplateArgument::Kind!");
1391}
1392
1393bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1394 return VisitDeclContext(D);
1395}
1396
1397bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1398 return Visit(TL.getUnqualifiedLoc());
1399}
1400
1401bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1402 ASTContext &Context = AU->getASTContext();
1403
1404 // Some builtin types (such as Objective-C's "id", "sel", and
1405 // "Class") have associated declarations. Create cursors for those.
1406 QualType VisitType;
1407 switch (TL.getTypePtr()->getKind()) {
1408
1409 case BuiltinType::Void:
1410 case BuiltinType::NullPtr:
1411 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001412 case BuiltinType::OCLImage1d:
1413 case BuiltinType::OCLImage1dArray:
1414 case BuiltinType::OCLImage1dBuffer:
1415 case BuiltinType::OCLImage2d:
1416 case BuiltinType::OCLImage2dArray:
1417 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001418 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001419 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001420#define BUILTIN_TYPE(Id, SingletonId)
1421#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1422#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1423#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1424#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1425#include "clang/AST/BuiltinTypes.def"
1426 break;
1427
1428 case BuiltinType::ObjCId:
1429 VisitType = Context.getObjCIdType();
1430 break;
1431
1432 case BuiltinType::ObjCClass:
1433 VisitType = Context.getObjCClassType();
1434 break;
1435
1436 case BuiltinType::ObjCSel:
1437 VisitType = Context.getObjCSelType();
1438 break;
1439 }
1440
1441 if (!VisitType.isNull()) {
1442 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1443 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1444 TU));
1445 }
1446
1447 return false;
1448}
1449
1450bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1451 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1452}
1453
1454bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1455 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1456}
1457
1458bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1459 if (TL.isDefinition())
1460 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1461
1462 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1463}
1464
1465bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1466 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1467}
1468
1469bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1470 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1471 return true;
1472
1473 return false;
1474}
1475
1476bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1477 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1478 return true;
1479
1480 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1481 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1482 TU)))
1483 return true;
1484 }
1485
1486 return false;
1487}
1488
1489bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1490 return Visit(TL.getPointeeLoc());
1491}
1492
1493bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1494 return Visit(TL.getInnerLoc());
1495}
1496
1497bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1498 return Visit(TL.getPointeeLoc());
1499}
1500
1501bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1502 return Visit(TL.getPointeeLoc());
1503}
1504
1505bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1506 return Visit(TL.getPointeeLoc());
1507}
1508
1509bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1510 return Visit(TL.getPointeeLoc());
1511}
1512
1513bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1514 return Visit(TL.getPointeeLoc());
1515}
1516
1517bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1518 return Visit(TL.getModifiedLoc());
1519}
1520
1521bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1522 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001523 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001524 return true;
1525
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001526 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1527 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001528 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1529 return true;
1530
1531 return false;
1532}
1533
1534bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1535 if (Visit(TL.getElementLoc()))
1536 return true;
1537
1538 if (Expr *Size = TL.getSizeExpr())
1539 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1540
1541 return false;
1542}
1543
Reid Kleckner8a365022013-06-24 17:51:48 +00001544bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1545 return Visit(TL.getOriginalLoc());
1546}
1547
Reid Kleckner0503a872013-12-05 01:23:43 +00001548bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1549 return Visit(TL.getOriginalLoc());
1550}
1551
Guy Benyei11169dd2012-12-18 14:30:41 +00001552bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1553 TemplateSpecializationTypeLoc TL) {
1554 // Visit the template name.
1555 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1556 TL.getTemplateNameLoc()))
1557 return true;
1558
1559 // Visit the template arguments.
1560 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1561 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1562 return true;
1563
1564 return false;
1565}
1566
1567bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1568 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1569}
1570
1571bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1572 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1573 return Visit(TSInfo->getTypeLoc());
1574
1575 return false;
1576}
1577
1578bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1579 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1580 return Visit(TSInfo->getTypeLoc());
1581
1582 return false;
1583}
1584
1585bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1586 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1587 return true;
1588
1589 return false;
1590}
1591
1592bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1593 DependentTemplateSpecializationTypeLoc TL) {
1594 // Visit the nested-name-specifier, if there is one.
1595 if (TL.getQualifierLoc() &&
1596 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1597 return true;
1598
1599 // Visit the template arguments.
1600 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1601 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1602 return true;
1603
1604 return false;
1605}
1606
1607bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1608 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1609 return true;
1610
1611 return Visit(TL.getNamedTypeLoc());
1612}
1613
1614bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1615 return Visit(TL.getPatternLoc());
1616}
1617
1618bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1619 if (Expr *E = TL.getUnderlyingExpr())
1620 return Visit(MakeCXCursor(E, StmtParent, TU));
1621
1622 return false;
1623}
1624
1625bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1626 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1627}
1628
1629bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1630 return Visit(TL.getValueLoc());
1631}
1632
1633#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1634bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1635 return Visit##PARENT##Loc(TL); \
1636}
1637
1638DEFAULT_TYPELOC_IMPL(Complex, Type)
1639DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1640DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1641DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1642DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1643DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1644DEFAULT_TYPELOC_IMPL(Vector, Type)
1645DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1646DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1647DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1648DEFAULT_TYPELOC_IMPL(Record, TagType)
1649DEFAULT_TYPELOC_IMPL(Enum, TagType)
1650DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1651DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1652DEFAULT_TYPELOC_IMPL(Auto, Type)
1653
1654bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1655 // Visit the nested-name-specifier, if present.
1656 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1657 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1658 return true;
1659
1660 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001661 for (const auto &I : D->bases()) {
1662 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001663 return true;
1664 }
1665 }
1666
1667 return VisitTagDecl(D);
1668}
1669
1670bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001671 for (const auto *I : D->attrs())
1672 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001673 return true;
1674
1675 return false;
1676}
1677
1678//===----------------------------------------------------------------------===//
1679// Data-recursive visitor methods.
1680//===----------------------------------------------------------------------===//
1681
1682namespace {
1683#define DEF_JOB(NAME, DATA, KIND)\
1684class NAME : public VisitorJob {\
1685public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001686 NAME(const DATA *d, CXCursor parent) : \
1687 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001688 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001689 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001690};
1691
1692DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1693DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1694DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1695DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1696DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1697 ExplicitTemplateArgsVisitKind)
1698DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1699DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1700DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1701#undef DEF_JOB
1702
1703class DeclVisit : public VisitorJob {
1704public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001705 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001706 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001707 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001708 static bool classof(const VisitorJob *VJ) {
1709 return VJ->getKind() == DeclVisitKind;
1710 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001711 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001712 bool isFirst() const { return data[1] ? true : false; }
1713};
1714class TypeLocVisit : public VisitorJob {
1715public:
1716 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1717 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1718 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1719
1720 static bool classof(const VisitorJob *VJ) {
1721 return VJ->getKind() == TypeLocVisitKind;
1722 }
1723
1724 TypeLoc get() const {
1725 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001726 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001727 }
1728};
1729
1730class LabelRefVisit : public VisitorJob {
1731public:
1732 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1733 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1734 labelLoc.getPtrEncoding()) {}
1735
1736 static bool classof(const VisitorJob *VJ) {
1737 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1738 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001739 const LabelDecl *get() const {
1740 return static_cast<const LabelDecl *>(data[0]);
1741 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001742 SourceLocation getLoc() const {
1743 return SourceLocation::getFromPtrEncoding(data[1]); }
1744};
1745
1746class NestedNameSpecifierLocVisit : public VisitorJob {
1747public:
1748 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1749 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1750 Qualifier.getNestedNameSpecifier(),
1751 Qualifier.getOpaqueData()) { }
1752
1753 static bool classof(const VisitorJob *VJ) {
1754 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1755 }
1756
1757 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001758 return NestedNameSpecifierLoc(
1759 const_cast<NestedNameSpecifier *>(
1760 static_cast<const NestedNameSpecifier *>(data[0])),
1761 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001762 }
1763};
1764
1765class DeclarationNameInfoVisit : public VisitorJob {
1766public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001767 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001768 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001769 static bool classof(const VisitorJob *VJ) {
1770 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1771 }
1772 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001773 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001774 switch (S->getStmtClass()) {
1775 default:
1776 llvm_unreachable("Unhandled Stmt");
1777 case clang::Stmt::MSDependentExistsStmtClass:
1778 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1779 case Stmt::CXXDependentScopeMemberExprClass:
1780 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1781 case Stmt::DependentScopeDeclRefExprClass:
1782 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1783 }
1784 }
1785};
1786class MemberRefVisit : public VisitorJob {
1787public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001788 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001789 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1790 L.getPtrEncoding()) {}
1791 static bool classof(const VisitorJob *VJ) {
1792 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1793 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001794 const FieldDecl *get() const {
1795 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001796 }
1797 SourceLocation getLoc() const {
1798 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1799 }
1800};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001801class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001802 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001803 VisitorWorkList &WL;
1804 CXCursor Parent;
1805public:
1806 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1807 : WL(wl), Parent(parent) {}
1808
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001809 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1810 void VisitBlockExpr(const BlockExpr *B);
1811 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1812 void VisitCompoundStmt(const CompoundStmt *S);
1813 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1814 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1815 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1816 void VisitCXXNewExpr(const CXXNewExpr *E);
1817 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1818 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1819 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1820 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1821 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1822 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1823 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1824 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1825 void VisitDeclRefExpr(const DeclRefExpr *D);
1826 void VisitDeclStmt(const DeclStmt *S);
1827 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1828 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1829 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1830 void VisitForStmt(const ForStmt *FS);
1831 void VisitGotoStmt(const GotoStmt *GS);
1832 void VisitIfStmt(const IfStmt *If);
1833 void VisitInitListExpr(const InitListExpr *IE);
1834 void VisitMemberExpr(const MemberExpr *M);
1835 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1836 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1837 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1838 void VisitOverloadExpr(const OverloadExpr *E);
1839 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1840 void VisitStmt(const Stmt *S);
1841 void VisitSwitchStmt(const SwitchStmt *S);
1842 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001843 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1844 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1845 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1846 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1847 void VisitVAArgExpr(const VAArgExpr *E);
1848 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1849 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1850 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1851 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001852 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1853 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001854 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001855
Guy Benyei11169dd2012-12-18 14:30:41 +00001856private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001857 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001858 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1859 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001860 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1861 void AddStmt(const Stmt *S);
1862 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001863 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001864 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001865 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001866};
1867} // end anonyous namespace
1868
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001869void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001870 // 'S' should always be non-null, since it comes from the
1871 // statement we are visiting.
1872 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1873}
1874
1875void
1876EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1877 if (Qualifier)
1878 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1879}
1880
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001881void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001882 if (S)
1883 WL.push_back(StmtVisit(S, Parent));
1884}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001885void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001886 if (D)
1887 WL.push_back(DeclVisit(D, Parent, isFirst));
1888}
1889void EnqueueVisitor::
1890 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1891 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001892 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001893}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001894void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001895 if (D)
1896 WL.push_back(MemberRefVisit(D, L, Parent));
1897}
1898void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1899 if (TI)
1900 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1901 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001903 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001904 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001905 AddStmt(*Child);
1906 }
1907 if (size == WL.size())
1908 return;
1909 // Now reverse the entries we just added. This will match the DFS
1910 // ordering performed by the worklist.
1911 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1912 std::reverse(I, E);
1913}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001914namespace {
1915class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1916 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001917 /// \brief Process clauses with list of variables.
1918 template <typename T>
1919 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001920public:
1921 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1922#define OPENMP_CLAUSE(Name, Class) \
1923 void Visit##Class(const Class *C);
1924#include "clang/Basic/OpenMPKinds.def"
1925};
1926
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001927void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1928 Visitor->AddStmt(C->getCondition());
1929}
1930
Alexey Bataev568a8332014-03-06 06:15:19 +00001931void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1932 Visitor->AddStmt(C->getNumThreads());
1933}
1934
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001935void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001936
1937template<typename T>
1938void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
1939 for (typename T::varlist_const_iterator I = Node->varlist_begin(),
1940 E = Node->varlist_end();
1941 I != E; ++I)
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001942 Visitor->AddStmt(*I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001943}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001944
1945void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001946 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001947}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001948void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1949 const OMPFirstprivateClause *C) {
1950 VisitOMPClauseList(C);
1951}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001952void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001953 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001954}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001955}
Alexey Bataev756c1962013-09-24 03:17:45 +00001956
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001957void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1958 unsigned size = WL.size();
1959 OMPClauseEnqueue Visitor(this);
1960 Visitor.Visit(S);
1961 if (size == WL.size())
1962 return;
1963 // Now reverse the entries we just added. This will match the DFS
1964 // ordering performed by the worklist.
1965 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1966 std::reverse(I, E);
1967}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001968void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001969 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1970}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001971void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001972 AddDecl(B->getBlockDecl());
1973}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001974void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001975 EnqueueChildren(E);
1976 AddTypeLoc(E->getTypeSourceInfo());
1977}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001978void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1979 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001980 E = S->body_rend(); I != E; ++I) {
1981 AddStmt(*I);
1982 }
1983}
1984void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001985VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001986 AddStmt(S->getSubStmt());
1987 AddDeclarationNameInfo(S);
1988 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1989 AddNestedNameSpecifierLoc(QualifierLoc);
1990}
1991
1992void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001993VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001994 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1995 AddDeclarationNameInfo(E);
1996 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1997 AddNestedNameSpecifierLoc(QualifierLoc);
1998 if (!E->isImplicitAccess())
1999 AddStmt(E->getBase());
2000}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002001void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002002 // Enqueue the initializer , if any.
2003 AddStmt(E->getInitializer());
2004 // Enqueue the array size, if any.
2005 AddStmt(E->getArraySize());
2006 // Enqueue the allocated type.
2007 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2008 // Enqueue the placement arguments.
2009 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2010 AddStmt(E->getPlacementArg(I-1));
2011}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002012void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002013 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2014 AddStmt(CE->getArg(I-1));
2015 AddStmt(CE->getCallee());
2016 AddStmt(CE->getArg(0));
2017}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002018void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2019 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002020 // Visit the name of the type being destroyed.
2021 AddTypeLoc(E->getDestroyedTypeInfo());
2022 // Visit the scope type that looks disturbingly like the nested-name-specifier
2023 // but isn't.
2024 AddTypeLoc(E->getScopeTypeInfo());
2025 // Visit the nested-name-specifier.
2026 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2027 AddNestedNameSpecifierLoc(QualifierLoc);
2028 // Visit base expression.
2029 AddStmt(E->getBase());
2030}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002031void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2032 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002033 AddTypeLoc(E->getTypeSourceInfo());
2034}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002035void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2036 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002037 EnqueueChildren(E);
2038 AddTypeLoc(E->getTypeSourceInfo());
2039}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002040void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002041 EnqueueChildren(E);
2042 if (E->isTypeOperand())
2043 AddTypeLoc(E->getTypeOperandSourceInfo());
2044}
2045
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002046void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2047 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002048 EnqueueChildren(E);
2049 AddTypeLoc(E->getTypeSourceInfo());
2050}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002051void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002052 EnqueueChildren(E);
2053 if (E->isTypeOperand())
2054 AddTypeLoc(E->getTypeOperandSourceInfo());
2055}
2056
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002057void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002058 EnqueueChildren(S);
2059 AddDecl(S->getExceptionDecl());
2060}
2061
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002062void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002063 if (DR->hasExplicitTemplateArgs()) {
2064 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2065 }
2066 WL.push_back(DeclRefExprParts(DR, Parent));
2067}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002068void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2069 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002070 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2071 AddDeclarationNameInfo(E);
2072 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2073}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002074void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002075 unsigned size = WL.size();
2076 bool isFirst = true;
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002077 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00002078 D != DEnd; ++D) {
2079 AddDecl(*D, isFirst);
2080 isFirst = false;
2081 }
2082 if (size == WL.size())
2083 return;
2084 // Now reverse the entries we just added. This will match the DFS
2085 // ordering performed by the worklist.
2086 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2087 std::reverse(I, E);
2088}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002089void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002090 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002091 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002092 D = E->designators_rbegin(), DEnd = E->designators_rend();
2093 D != DEnd; ++D) {
2094 if (D->isFieldDesignator()) {
2095 if (FieldDecl *Field = D->getField())
2096 AddMemberRef(Field, D->getFieldLoc());
2097 continue;
2098 }
2099 if (D->isArrayDesignator()) {
2100 AddStmt(E->getArrayIndex(*D));
2101 continue;
2102 }
2103 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2104 AddStmt(E->getArrayRangeEnd(*D));
2105 AddStmt(E->getArrayRangeStart(*D));
2106 }
2107}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002108void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002109 EnqueueChildren(E);
2110 AddTypeLoc(E->getTypeInfoAsWritten());
2111}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002112void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002113 AddStmt(FS->getBody());
2114 AddStmt(FS->getInc());
2115 AddStmt(FS->getCond());
2116 AddDecl(FS->getConditionVariable());
2117 AddStmt(FS->getInit());
2118}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002119void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002120 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2121}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002122void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002123 AddStmt(If->getElse());
2124 AddStmt(If->getThen());
2125 AddStmt(If->getCond());
2126 AddDecl(If->getConditionVariable());
2127}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002128void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002129 // We care about the syntactic form of the initializer list, only.
2130 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2131 IE = Syntactic;
2132 EnqueueChildren(IE);
2133}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002134void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002135 WL.push_back(MemberExprParts(M, Parent));
2136
2137 // If the base of the member access expression is an implicit 'this', don't
2138 // visit it.
2139 // FIXME: If we ever want to show these implicit accesses, this will be
2140 // unfortunate. However, clang_getCursor() relies on this behavior.
2141 if (!M->isImplicitAccess())
2142 AddStmt(M->getBase());
2143}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002144void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002145 AddTypeLoc(E->getEncodedTypeSourceInfo());
2146}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002147void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002148 EnqueueChildren(M);
2149 AddTypeLoc(M->getClassReceiverTypeInfo());
2150}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002151void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002152 // Visit the components of the offsetof expression.
2153 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2154 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2155 const OffsetOfNode &Node = E->getComponent(I-1);
2156 switch (Node.getKind()) {
2157 case OffsetOfNode::Array:
2158 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2159 break;
2160 case OffsetOfNode::Field:
2161 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2162 break;
2163 case OffsetOfNode::Identifier:
2164 case OffsetOfNode::Base:
2165 continue;
2166 }
2167 }
2168 // Visit the type into which we're computing the offset.
2169 AddTypeLoc(E->getTypeSourceInfo());
2170}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002171void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002172 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2173 WL.push_back(OverloadExprParts(E, Parent));
2174}
2175void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002176 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002177 EnqueueChildren(E);
2178 if (E->isArgumentType())
2179 AddTypeLoc(E->getArgumentTypeInfo());
2180}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002181void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002182 EnqueueChildren(S);
2183}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002184void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002185 AddStmt(S->getBody());
2186 AddStmt(S->getCond());
2187 AddDecl(S->getConditionVariable());
2188}
2189
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002190void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002191 AddStmt(W->getBody());
2192 AddStmt(W->getCond());
2193 AddDecl(W->getConditionVariable());
2194}
2195
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002196void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002197 for (unsigned I = E->getNumArgs(); I > 0; --I)
2198 AddTypeLoc(E->getArg(I-1));
2199}
2200
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002201void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002202 AddTypeLoc(E->getQueriedTypeSourceInfo());
2203}
2204
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002205void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002206 EnqueueChildren(E);
2207}
2208
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002209void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002210 VisitOverloadExpr(U);
2211 if (!U->isImplicitAccess())
2212 AddStmt(U->getBase());
2213}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002214void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002215 AddStmt(E->getSubExpr());
2216 AddTypeLoc(E->getWrittenTypeInfo());
2217}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 WL.push_back(SizeOfPackExprParts(E, Parent));
2220}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002221void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002222 // If the opaque value has a source expression, just transparently
2223 // visit that. This is useful for (e.g.) pseudo-object expressions.
2224 if (Expr *SourceExpr = E->getSourceExpr())
2225 return Visit(SourceExpr);
2226}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002227void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002228 AddStmt(E->getBody());
2229 WL.push_back(LambdaExprParts(E, Parent));
2230}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002231void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002232 // Treat the expression like its syntactic form.
2233 Visit(E->getSyntacticForm());
2234}
2235
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002236void EnqueueVisitor::VisitOMPExecutableDirective(
2237 const OMPExecutableDirective *D) {
2238 EnqueueChildren(D);
2239 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2240 E = D->clauses().end();
2241 I != E; ++I)
2242 EnqueueChildren(*I);
2243}
2244
2245void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2246 VisitOMPExecutableDirective(D);
2247}
2248
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002249void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2250 VisitOMPExecutableDirective(D);
2251}
2252
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002253void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002254 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2255}
2256
2257bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2258 if (RegionOfInterest.isValid()) {
2259 SourceRange Range = getRawCursorExtent(C);
2260 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2261 return false;
2262 }
2263 return true;
2264}
2265
2266bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2267 while (!WL.empty()) {
2268 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002269 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002270
2271 // Set the Parent field, then back to its old value once we're done.
2272 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2273
2274 switch (LI.getKind()) {
2275 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002276 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002277 if (!D)
2278 continue;
2279
2280 // For now, perform default visitation for Decls.
2281 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2282 cast<DeclVisit>(&LI)->isFirst())))
2283 return true;
2284
2285 continue;
2286 }
2287 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2288 const ASTTemplateArgumentListInfo *ArgList =
2289 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2290 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2291 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2292 Arg != ArgEnd; ++Arg) {
2293 if (VisitTemplateArgumentLoc(*Arg))
2294 return true;
2295 }
2296 continue;
2297 }
2298 case VisitorJob::TypeLocVisitKind: {
2299 // Perform default visitation for TypeLocs.
2300 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2301 return true;
2302 continue;
2303 }
2304 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002305 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002306 if (LabelStmt *stmt = LS->getStmt()) {
2307 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2308 TU))) {
2309 return true;
2310 }
2311 }
2312 continue;
2313 }
2314
2315 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2316 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2317 if (VisitNestedNameSpecifierLoc(V->get()))
2318 return true;
2319 continue;
2320 }
2321
2322 case VisitorJob::DeclarationNameInfoVisitKind: {
2323 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2324 ->get()))
2325 return true;
2326 continue;
2327 }
2328 case VisitorJob::MemberRefVisitKind: {
2329 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2330 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2331 return true;
2332 continue;
2333 }
2334 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002335 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002336 if (!S)
2337 continue;
2338
2339 // Update the current cursor.
2340 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2341 if (!IsInRegionOfInterest(Cursor))
2342 continue;
2343 switch (Visitor(Cursor, Parent, ClientData)) {
2344 case CXChildVisit_Break: return true;
2345 case CXChildVisit_Continue: break;
2346 case CXChildVisit_Recurse:
2347 if (PostChildrenVisitor)
2348 WL.push_back(PostChildrenVisit(0, Cursor));
2349 EnqueueWorkList(WL, S);
2350 break;
2351 }
2352 continue;
2353 }
2354 case VisitorJob::MemberExprPartsKind: {
2355 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002356 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002357
2358 // Visit the nested-name-specifier
2359 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2360 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2361 return true;
2362
2363 // Visit the declaration name.
2364 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2365 return true;
2366
2367 // Visit the explicitly-specified template arguments, if any.
2368 if (M->hasExplicitTemplateArgs()) {
2369 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2370 *ArgEnd = Arg + M->getNumTemplateArgs();
2371 Arg != ArgEnd; ++Arg) {
2372 if (VisitTemplateArgumentLoc(*Arg))
2373 return true;
2374 }
2375 }
2376 continue;
2377 }
2378 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002379 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002380 // Visit nested-name-specifier, if present.
2381 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2382 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2383 return true;
2384 // Visit declaration name.
2385 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2386 return true;
2387 continue;
2388 }
2389 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002390 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002391 // Visit the nested-name-specifier.
2392 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2393 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2394 return true;
2395 // Visit the declaration name.
2396 if (VisitDeclarationNameInfo(O->getNameInfo()))
2397 return true;
2398 // Visit the overloaded declaration reference.
2399 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2400 return true;
2401 continue;
2402 }
2403 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002404 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002405 NamedDecl *Pack = E->getPack();
2406 if (isa<TemplateTypeParmDecl>(Pack)) {
2407 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2408 E->getPackLoc(), TU)))
2409 return true;
2410
2411 continue;
2412 }
2413
2414 if (isa<TemplateTemplateParmDecl>(Pack)) {
2415 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2416 E->getPackLoc(), TU)))
2417 return true;
2418
2419 continue;
2420 }
2421
2422 // Non-type template parameter packs and function parameter packs are
2423 // treated like DeclRefExpr cursors.
2424 continue;
2425 }
2426
2427 case VisitorJob::LambdaExprPartsKind: {
2428 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002429 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002430 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2431 CEnd = E->explicit_capture_end();
2432 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002433 // FIXME: Lambda init-captures.
2434 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002435 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002436
Guy Benyei11169dd2012-12-18 14:30:41 +00002437 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2438 C->getLocation(),
2439 TU)))
2440 return true;
2441 }
2442
2443 // Visit parameters and return type, if present.
2444 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2445 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2446 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2447 // Visit the whole type.
2448 if (Visit(TL))
2449 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002450 } else if (FunctionProtoTypeLoc Proto =
2451 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002452 if (E->hasExplicitParameters()) {
2453 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002454 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2455 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002456 return true;
2457 } else {
2458 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002459 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002460 return true;
2461 }
2462 }
2463 }
2464 break;
2465 }
2466
2467 case VisitorJob::PostChildrenVisitKind:
2468 if (PostChildrenVisitor(Parent, ClientData))
2469 return true;
2470 break;
2471 }
2472 }
2473 return false;
2474}
2475
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002476bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002477 VisitorWorkList *WL = 0;
2478 if (!WorkListFreeList.empty()) {
2479 WL = WorkListFreeList.back();
2480 WL->clear();
2481 WorkListFreeList.pop_back();
2482 }
2483 else {
2484 WL = new VisitorWorkList();
2485 WorkListCache.push_back(WL);
2486 }
2487 EnqueueWorkList(*WL, S);
2488 bool result = RunVisitorWorkList(*WL);
2489 WorkListFreeList.push_back(WL);
2490 return result;
2491}
2492
2493namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002494typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002495RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2496 const DeclarationNameInfo &NI,
2497 const SourceRange &QLoc,
2498 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2499 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2500 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2501 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2502
2503 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2504
2505 RefNamePieces Pieces;
2506
2507 if (WantQualifier && QLoc.isValid())
2508 Pieces.push_back(QLoc);
2509
2510 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2511 Pieces.push_back(NI.getLoc());
2512
2513 if (WantTemplateArgs && TemplateArgs)
2514 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2515 TemplateArgs->RAngleLoc));
2516
2517 if (Kind == DeclarationName::CXXOperatorName) {
2518 Pieces.push_back(SourceLocation::getFromRawEncoding(
2519 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2520 Pieces.push_back(SourceLocation::getFromRawEncoding(
2521 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2522 }
2523
2524 if (WantSinglePiece) {
2525 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2526 Pieces.clear();
2527 Pieces.push_back(R);
2528 }
2529
2530 return Pieces;
2531}
2532}
2533
2534//===----------------------------------------------------------------------===//
2535// Misc. API hooks.
2536//===----------------------------------------------------------------------===//
2537
2538static llvm::sys::Mutex EnableMultithreadingMutex;
2539static bool EnabledMultithreading;
2540
Chad Rosier05c71aa2013-03-27 18:28:23 +00002541static void fatal_error_handler(void *user_data, const std::string& reason,
2542 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002543 // Write the result out to stderr avoiding errs() because raw_ostreams can
2544 // call report_fatal_error.
2545 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2546 ::abort();
2547}
2548
2549extern "C" {
2550CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2551 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002552 // We use crash recovery to make some of our APIs more reliable, implicitly
2553 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002554 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2555 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002556
2557 // Enable support for multithreading in LLVM.
2558 {
2559 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2560 if (!EnabledMultithreading) {
2561 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2562 llvm::llvm_start_multithreaded();
2563 EnabledMultithreading = true;
2564 }
2565 }
2566
2567 CIndexer *CIdxr = new CIndexer();
2568 if (excludeDeclarationsFromPCH)
2569 CIdxr->setOnlyLocalDecls();
2570 if (displayDiagnostics)
2571 CIdxr->setDisplayDiagnostics();
2572
2573 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2574 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2575 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2576 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2577 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2578 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2579
2580 return CIdxr;
2581}
2582
2583void clang_disposeIndex(CXIndex CIdx) {
2584 if (CIdx)
2585 delete static_cast<CIndexer *>(CIdx);
2586}
2587
2588void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2589 if (CIdx)
2590 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2591}
2592
2593unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2594 if (CIdx)
2595 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2596 return 0;
2597}
2598
2599void clang_toggleCrashRecovery(unsigned isEnabled) {
2600 if (isEnabled)
2601 llvm::CrashRecoveryContext::Enable();
2602 else
2603 llvm::CrashRecoveryContext::Disable();
2604}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002605
Guy Benyei11169dd2012-12-18 14:30:41 +00002606CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2607 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002608 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002609 enum CXErrorCode Result =
2610 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002611 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002612 assert((TU && Result == CXError_Success) ||
2613 (!TU && Result != CXError_Success));
2614 return TU;
2615}
2616
2617enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2618 const char *ast_filename,
2619 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002620 if (out_TU)
2621 *out_TU = NULL;
2622
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002623 if (!CIdx || !ast_filename || !out_TU)
2624 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002625
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002626 LOG_FUNC_SECTION {
2627 *Log << ast_filename;
2628 }
2629
Guy Benyei11169dd2012-12-18 14:30:41 +00002630 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2631 FileSystemOptions FileSystemOpts;
2632
2633 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002634 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002635 CXXIdx->getOnlyLocalDecls(), None,
2636 /*CaptureDiagnostics=*/true,
2637 /*AllowPCHWithCompilerErrors=*/true,
2638 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002639 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2640 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002641}
2642
2643unsigned clang_defaultEditingTranslationUnitOptions() {
2644 return CXTranslationUnit_PrecompiledPreamble |
2645 CXTranslationUnit_CacheCompletionResults;
2646}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002647
Guy Benyei11169dd2012-12-18 14:30:41 +00002648CXTranslationUnit
2649clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2650 const char *source_filename,
2651 int num_command_line_args,
2652 const char * const *command_line_args,
2653 unsigned num_unsaved_files,
2654 struct CXUnsavedFile *unsaved_files) {
2655 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2656 return clang_parseTranslationUnit(CIdx, source_filename,
2657 command_line_args, num_command_line_args,
2658 unsaved_files, num_unsaved_files,
2659 Options);
2660}
2661
2662struct ParseTranslationUnitInfo {
2663 CXIndex CIdx;
2664 const char *source_filename;
2665 const char *const *command_line_args;
2666 int num_command_line_args;
2667 struct CXUnsavedFile *unsaved_files;
2668 unsigned num_unsaved_files;
2669 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002670 CXTranslationUnit *out_TU;
2671 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002672};
2673static void clang_parseTranslationUnit_Impl(void *UserData) {
2674 ParseTranslationUnitInfo *PTUI =
2675 static_cast<ParseTranslationUnitInfo*>(UserData);
2676 CXIndex CIdx = PTUI->CIdx;
2677 const char *source_filename = PTUI->source_filename;
2678 const char * const *command_line_args = PTUI->command_line_args;
2679 int num_command_line_args = PTUI->num_command_line_args;
2680 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2681 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2682 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002683 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002684
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002685 // Set up the initial return values.
2686 if (out_TU)
2687 *out_TU = NULL;
2688 PTUI->result = CXError_Failure;
2689
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002690 // Check arguments.
2691 if (!CIdx || !out_TU ||
2692 (unsaved_files == NULL && num_unsaved_files != 0)) {
2693 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002694 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002695 }
2696
Guy Benyei11169dd2012-12-18 14:30:41 +00002697 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2698
2699 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2700 setThreadBackgroundPriority();
2701
2702 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2703 // FIXME: Add a flag for modules.
2704 TranslationUnitKind TUKind
2705 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002706 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002707 = options & CXTranslationUnit_CacheCompletionResults;
2708 bool IncludeBriefCommentsInCodeCompletion
2709 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2710 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2711 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2712
2713 // Configure the diagnostics.
2714 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002715 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002716
2717 // Recover resources if we crash before exiting this function.
2718 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2719 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2720 DiagCleanup(Diags.getPtr());
2721
Ahmed Charlesb8984322014-03-07 20:03:18 +00002722 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2723 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002724
2725 // Recover resources if we crash before exiting this function.
2726 llvm::CrashRecoveryContextCleanupRegistrar<
2727 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2728
2729 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2730 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2731 const llvm::MemoryBuffer *Buffer
2732 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2733 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2734 Buffer));
2735 }
2736
Ahmed Charlesb8984322014-03-07 20:03:18 +00002737 std::unique_ptr<std::vector<const char *>> Args(
2738 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002739
2740 // Recover resources if we crash before exiting this method.
2741 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2742 ArgsCleanup(Args.get());
2743
2744 // Since the Clang C library is primarily used by batch tools dealing with
2745 // (often very broken) source code, where spell-checking can have a
2746 // significant negative impact on performance (particularly when
2747 // precompiled headers are involved), we disable it by default.
2748 // Only do this if we haven't found a spell-checking-related argument.
2749 bool FoundSpellCheckingArgument = false;
2750 for (int I = 0; I != num_command_line_args; ++I) {
2751 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2752 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2753 FoundSpellCheckingArgument = true;
2754 break;
2755 }
2756 }
2757 if (!FoundSpellCheckingArgument)
2758 Args->push_back("-fno-spell-checking");
2759
2760 Args->insert(Args->end(), command_line_args,
2761 command_line_args + num_command_line_args);
2762
2763 // The 'source_filename' argument is optional. If the caller does not
2764 // specify it then it is assumed that the source file is specified
2765 // in the actual argument list.
2766 // Put the source file after command_line_args otherwise if '-x' flag is
2767 // present it will be unused.
2768 if (source_filename)
2769 Args->push_back(source_filename);
2770
2771 // Do we need the detailed preprocessing record?
2772 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2773 Args->push_back("-Xclang");
2774 Args->push_back("-detailed-preprocessing-record");
2775 }
2776
2777 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002778 std::unique_ptr<ASTUnit> ErrUnit;
2779 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002780 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002781 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2782 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2783 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2784 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2785 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2786 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002787
2788 if (NumErrors != Diags->getClient()->getNumErrors()) {
2789 // Make sure to check that 'Unit' is non-NULL.
2790 if (CXXIdx->getDisplayDiagnostics())
2791 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2792 }
2793
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002794 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2795 PTUI->result = CXError_ASTReadError;
2796 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002797 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002798 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2799 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002800}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002801
2802CXTranslationUnit
2803clang_parseTranslationUnit(CXIndex CIdx,
2804 const char *source_filename,
2805 const char *const *command_line_args,
2806 int num_command_line_args,
2807 struct CXUnsavedFile *unsaved_files,
2808 unsigned num_unsaved_files,
2809 unsigned options) {
2810 CXTranslationUnit TU;
2811 enum CXErrorCode Result = clang_parseTranslationUnit2(
2812 CIdx, source_filename, command_line_args, num_command_line_args,
2813 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002814 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002815 assert((TU && Result == CXError_Success) ||
2816 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002817 return TU;
2818}
2819
2820enum CXErrorCode clang_parseTranslationUnit2(
2821 CXIndex CIdx,
2822 const char *source_filename,
2823 const char *const *command_line_args,
2824 int num_command_line_args,
2825 struct CXUnsavedFile *unsaved_files,
2826 unsigned num_unsaved_files,
2827 unsigned options,
2828 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002829 LOG_FUNC_SECTION {
2830 *Log << source_filename << ": ";
2831 for (int i = 0; i != num_command_line_args; ++i)
2832 *Log << command_line_args[i] << " ";
2833 }
2834
Guy Benyei11169dd2012-12-18 14:30:41 +00002835 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2836 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002837 num_unsaved_files, options, out_TU,
2838 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002839 llvm::CrashRecoveryContext CRC;
2840
2841 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2842 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2843 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2844 fprintf(stderr, " 'command_line_args' : [");
2845 for (int i = 0; i != num_command_line_args; ++i) {
2846 if (i)
2847 fprintf(stderr, ", ");
2848 fprintf(stderr, "'%s'", command_line_args[i]);
2849 }
2850 fprintf(stderr, "],\n");
2851 fprintf(stderr, " 'unsaved_files' : [");
2852 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2853 if (i)
2854 fprintf(stderr, ", ");
2855 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2856 unsaved_files[i].Length);
2857 }
2858 fprintf(stderr, "],\n");
2859 fprintf(stderr, " 'options' : %d,\n", options);
2860 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002861
2862 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002863 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002864 if (CXTranslationUnit *TU = PTUI.out_TU)
2865 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002866 }
2867
2868 return PTUI.result;
2869}
2870
2871unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2872 return CXSaveTranslationUnit_None;
2873}
2874
2875namespace {
2876
2877struct SaveTranslationUnitInfo {
2878 CXTranslationUnit TU;
2879 const char *FileName;
2880 unsigned options;
2881 CXSaveError result;
2882};
2883
2884}
2885
2886static void clang_saveTranslationUnit_Impl(void *UserData) {
2887 SaveTranslationUnitInfo *STUI =
2888 static_cast<SaveTranslationUnitInfo*>(UserData);
2889
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002890 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002891 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2892 setThreadBackgroundPriority();
2893
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002894 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002895 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2896}
2897
2898int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2899 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002900 LOG_FUNC_SECTION {
2901 *Log << TU << ' ' << FileName;
2902 }
2903
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002904 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002905 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002906 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002907 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002908
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002909 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002910 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2911 if (!CXXUnit->hasSema())
2912 return CXSaveError_InvalidTU;
2913
2914 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2915
2916 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2917 getenv("LIBCLANG_NOTHREADS")) {
2918 clang_saveTranslationUnit_Impl(&STUI);
2919
2920 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2921 PrintLibclangResourceUsage(TU);
2922
2923 return STUI.result;
2924 }
2925
2926 // We have an AST that has invalid nodes due to compiler errors.
2927 // Use a crash recovery thread for protection.
2928
2929 llvm::CrashRecoveryContext CRC;
2930
2931 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2932 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2933 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2934 fprintf(stderr, " 'options' : %d,\n", options);
2935 fprintf(stderr, "}\n");
2936
2937 return CXSaveError_Unknown;
2938
2939 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2940 PrintLibclangResourceUsage(TU);
2941 }
2942
2943 return STUI.result;
2944}
2945
2946void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2947 if (CTUnit) {
2948 // If the translation unit has been marked as unsafe to free, just discard
2949 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002950 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2951 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002952 return;
2953
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002954 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002955 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002956 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2957 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002958 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002959 delete CTUnit;
2960 }
2961}
2962
2963unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2964 return CXReparse_None;
2965}
2966
2967struct ReparseTranslationUnitInfo {
2968 CXTranslationUnit TU;
2969 unsigned num_unsaved_files;
2970 struct CXUnsavedFile *unsaved_files;
2971 unsigned options;
2972 int result;
2973};
2974
2975static void clang_reparseTranslationUnit_Impl(void *UserData) {
2976 ReparseTranslationUnitInfo *RTUI =
2977 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002978 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002979
Guy Benyei11169dd2012-12-18 14:30:41 +00002980 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002981 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2982 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2983 unsigned options = RTUI->options;
2984 (void) options;
2985
2986 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002987 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002988 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002989 RTUI->result = CXError_InvalidArguments;
2990 return;
2991 }
2992 if (unsaved_files == NULL && num_unsaved_files != 0) {
2993 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00002994 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002995 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002996
2997 // Reset the associated diagnostics.
2998 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
2999 TU->Diagnostics = 0;
3000
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003001 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003002 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3003 setThreadBackgroundPriority();
3004
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003005 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003006 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003007
3008 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3009 new std::vector<ASTUnit::RemappedFile>());
3010
Guy Benyei11169dd2012-12-18 14:30:41 +00003011 // Recover resources if we crash before exiting this function.
3012 llvm::CrashRecoveryContextCleanupRegistrar<
3013 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3014
3015 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3016 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3017 const llvm::MemoryBuffer *Buffer
3018 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3019 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3020 Buffer));
3021 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003022
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003023 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003024 RTUI->result = CXError_Success;
3025 else if (isASTReadError(CXXUnit))
3026 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003027}
3028
3029int clang_reparseTranslationUnit(CXTranslationUnit TU,
3030 unsigned num_unsaved_files,
3031 struct CXUnsavedFile *unsaved_files,
3032 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003033 LOG_FUNC_SECTION {
3034 *Log << TU;
3035 }
3036
Guy Benyei11169dd2012-12-18 14:30:41 +00003037 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003038 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003039
3040 if (getenv("LIBCLANG_NOTHREADS")) {
3041 clang_reparseTranslationUnit_Impl(&RTUI);
3042 return RTUI.result;
3043 }
3044
3045 llvm::CrashRecoveryContext CRC;
3046
3047 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3048 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003049 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003050 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003051 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3052 PrintLibclangResourceUsage(TU);
3053
3054 return RTUI.result;
3055}
3056
3057
3058CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003059 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003060 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003061 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003062 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003063
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003064 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003065 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003066}
3067
3068CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003069 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003070 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003071 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003072 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003073
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003074 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003075 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3076}
3077
3078} // end: extern "C"
3079
3080//===----------------------------------------------------------------------===//
3081// CXFile Operations.
3082//===----------------------------------------------------------------------===//
3083
3084extern "C" {
3085CXString clang_getFileName(CXFile SFile) {
3086 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003087 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003088
3089 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003090 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003091}
3092
3093time_t clang_getFileTime(CXFile SFile) {
3094 if (!SFile)
3095 return 0;
3096
3097 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3098 return FEnt->getModificationTime();
3099}
3100
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003101CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003102 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003103 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003104 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003105 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003106
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003107 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003108
3109 FileManager &FMgr = CXXUnit->getFileManager();
3110 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3111}
3112
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003113unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3114 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003115 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003116 LOG_BAD_TU(TU);
3117 return 0;
3118 }
3119
3120 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003121 return 0;
3122
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003123 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003124 FileEntry *FEnt = static_cast<FileEntry *>(file);
3125 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3126 .isFileMultipleIncludeGuarded(FEnt);
3127}
3128
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003129int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3130 if (!file || !outID)
3131 return 1;
3132
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003133 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003134 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3135 outID->data[0] = ID.getDevice();
3136 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003137 outID->data[2] = FEnt->getModificationTime();
3138 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003139}
3140
Guy Benyei11169dd2012-12-18 14:30:41 +00003141} // end: extern "C"
3142
3143//===----------------------------------------------------------------------===//
3144// CXCursor Operations.
3145//===----------------------------------------------------------------------===//
3146
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003147static const Decl *getDeclFromExpr(const Stmt *E) {
3148 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003149 return getDeclFromExpr(CE->getSubExpr());
3150
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003151 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003152 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003153 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003154 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003155 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003156 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003157 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003158 if (PRE->isExplicitProperty())
3159 return PRE->getExplicitProperty();
3160 // It could be messaging both getter and setter as in:
3161 // ++myobj.myprop;
3162 // in which case prefer to associate the setter since it is less obvious
3163 // from inspecting the source that the setter is going to get called.
3164 if (PRE->isMessagingSetter())
3165 return PRE->getImplicitPropertySetter();
3166 return PRE->getImplicitPropertyGetter();
3167 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003168 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003169 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003170 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003171 if (Expr *Src = OVE->getSourceExpr())
3172 return getDeclFromExpr(Src);
3173
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003174 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003175 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003176 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003177 if (!CE->isElidable())
3178 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003179 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003180 return OME->getMethodDecl();
3181
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003182 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003183 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003184 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003185 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3186 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003187 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003188 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3189 isa<ParmVarDecl>(SizeOfPack->getPack()))
3190 return SizeOfPack->getPack();
3191
3192 return 0;
3193}
3194
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003195static SourceLocation getLocationFromExpr(const Expr *E) {
3196 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003197 return getLocationFromExpr(CE->getSubExpr());
3198
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003199 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003200 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003201 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003202 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003203 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003204 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003205 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003206 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003207 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003208 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003209 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003210 return PropRef->getLocation();
3211
3212 return E->getLocStart();
3213}
3214
3215extern "C" {
3216
3217unsigned clang_visitChildren(CXCursor parent,
3218 CXCursorVisitor visitor,
3219 CXClientData client_data) {
3220 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3221 /*VisitPreprocessorLast=*/false);
3222 return CursorVis.VisitChildren(parent);
3223}
3224
3225#ifndef __has_feature
3226#define __has_feature(x) 0
3227#endif
3228#if __has_feature(blocks)
3229typedef enum CXChildVisitResult
3230 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3231
3232static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3233 CXClientData client_data) {
3234 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3235 return block(cursor, parent);
3236}
3237#else
3238// If we are compiled with a compiler that doesn't have native blocks support,
3239// define and call the block manually, so the
3240typedef struct _CXChildVisitResult
3241{
3242 void *isa;
3243 int flags;
3244 int reserved;
3245 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3246 CXCursor);
3247} *CXCursorVisitorBlock;
3248
3249static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3250 CXClientData client_data) {
3251 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3252 return block->invoke(block, cursor, parent);
3253}
3254#endif
3255
3256
3257unsigned clang_visitChildrenWithBlock(CXCursor parent,
3258 CXCursorVisitorBlock block) {
3259 return clang_visitChildren(parent, visitWithBlock, block);
3260}
3261
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003262static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003263 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003264 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003265
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003266 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003267 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003268 if (const ObjCPropertyImplDecl *PropImpl =
3269 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003270 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003271 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003272
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003273 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003274 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003275 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003276
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003277 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003278 }
3279
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003280 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003281 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003282
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003283 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003284 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3285 // and returns different names. NamedDecl returns the class name and
3286 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003287 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003288
3289 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003290 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003291
3292 SmallString<1024> S;
3293 llvm::raw_svector_ostream os(S);
3294 ND->printName(os);
3295
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003296 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003297}
3298
3299CXString clang_getCursorSpelling(CXCursor C) {
3300 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003301 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003302
3303 if (clang_isReference(C.kind)) {
3304 switch (C.kind) {
3305 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003306 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003307 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003308 }
3309 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003310 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003311 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003312 }
3313 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003314 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003315 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003316 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003317 }
3318 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003319 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003320 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003321 }
3322 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003323 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003324 assert(Type && "Missing type decl");
3325
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003326 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003327 getAsString());
3328 }
3329 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003330 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003331 assert(Template && "Missing template decl");
3332
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003333 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 }
3335
3336 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003337 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 assert(NS && "Missing namespace decl");
3339
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003340 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003341 }
3342
3343 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003344 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003345 assert(Field && "Missing member decl");
3346
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003347 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 }
3349
3350 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003351 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003352 assert(Label && "Missing label");
3353
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003354 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003355 }
3356
3357 case CXCursor_OverloadedDeclRef: {
3358 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003359 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3360 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003361 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003362 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003363 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003364 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003365 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003366 OverloadedTemplateStorage *Ovl
3367 = Storage.get<OverloadedTemplateStorage*>();
3368 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003369 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003370 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003371 }
3372
3373 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003374 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003375 assert(Var && "Missing variable decl");
3376
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003377 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 }
3379
3380 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003381 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003382 }
3383 }
3384
3385 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003386 const Expr *E = getCursorExpr(C);
3387
3388 if (C.kind == CXCursor_ObjCStringLiteral ||
3389 C.kind == CXCursor_StringLiteral) {
3390 const StringLiteral *SLit;
3391 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3392 SLit = OSL->getString();
3393 } else {
3394 SLit = cast<StringLiteral>(E);
3395 }
3396 SmallString<256> Buf;
3397 llvm::raw_svector_ostream OS(Buf);
3398 SLit->outputString(OS);
3399 return cxstring::createDup(OS.str());
3400 }
3401
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003402 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003403 if (D)
3404 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003405 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003406 }
3407
3408 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003409 const Stmt *S = getCursorStmt(C);
3410 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003411 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003412
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003413 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003414 }
3415
3416 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003417 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003418 ->getNameStart());
3419
3420 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003421 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003422 ->getNameStart());
3423
3424 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003425 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003426
3427 if (clang_isDeclaration(C.kind))
3428 return getDeclSpelling(getCursorDecl(C));
3429
3430 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003431 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003432 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003433 }
3434
3435 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003436 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003437 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003438 }
3439
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003440 if (C.kind == CXCursor_PackedAttr) {
3441 return cxstring::createRef("packed");
3442 }
3443
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003444 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003445}
3446
3447CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3448 unsigned pieceIndex,
3449 unsigned options) {
3450 if (clang_Cursor_isNull(C))
3451 return clang_getNullRange();
3452
3453 ASTContext &Ctx = getCursorContext(C);
3454
3455 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003456 const Stmt *S = getCursorStmt(C);
3457 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003458 if (pieceIndex > 0)
3459 return clang_getNullRange();
3460 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3461 }
3462
3463 return clang_getNullRange();
3464 }
3465
3466 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003467 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003468 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3469 if (pieceIndex >= ME->getNumSelectorLocs())
3470 return clang_getNullRange();
3471 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3472 }
3473 }
3474
3475 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3476 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003477 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003478 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3479 if (pieceIndex >= MD->getNumSelectorLocs())
3480 return clang_getNullRange();
3481 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3482 }
3483 }
3484
3485 if (C.kind == CXCursor_ObjCCategoryDecl ||
3486 C.kind == CXCursor_ObjCCategoryImplDecl) {
3487 if (pieceIndex > 0)
3488 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003489 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003490 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3491 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003492 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003493 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3494 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3495 }
3496
3497 if (C.kind == CXCursor_ModuleImportDecl) {
3498 if (pieceIndex > 0)
3499 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003500 if (const ImportDecl *ImportD =
3501 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003502 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3503 if (!Locs.empty())
3504 return cxloc::translateSourceRange(Ctx,
3505 SourceRange(Locs.front(), Locs.back()));
3506 }
3507 return clang_getNullRange();
3508 }
3509
3510 // FIXME: A CXCursor_InclusionDirective should give the location of the
3511 // filename, but we don't keep track of this.
3512
3513 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3514 // but we don't keep track of this.
3515
3516 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3517 // but we don't keep track of this.
3518
3519 // Default handling, give the location of the cursor.
3520
3521 if (pieceIndex > 0)
3522 return clang_getNullRange();
3523
3524 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3525 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3526 return cxloc::translateSourceRange(Ctx, Loc);
3527}
3528
3529CXString clang_getCursorDisplayName(CXCursor C) {
3530 if (!clang_isDeclaration(C.kind))
3531 return clang_getCursorSpelling(C);
3532
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003533 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003534 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003535 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003536
3537 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003538 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003539 D = FunTmpl->getTemplatedDecl();
3540
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003541 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003542 SmallString<64> Str;
3543 llvm::raw_svector_ostream OS(Str);
3544 OS << *Function;
3545 if (Function->getPrimaryTemplate())
3546 OS << "<>";
3547 OS << "(";
3548 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3549 if (I)
3550 OS << ", ";
3551 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3552 }
3553
3554 if (Function->isVariadic()) {
3555 if (Function->getNumParams())
3556 OS << ", ";
3557 OS << "...";
3558 }
3559 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003560 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003561 }
3562
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003563 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003564 SmallString<64> Str;
3565 llvm::raw_svector_ostream OS(Str);
3566 OS << *ClassTemplate;
3567 OS << "<";
3568 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3569 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3570 if (I)
3571 OS << ", ";
3572
3573 NamedDecl *Param = Params->getParam(I);
3574 if (Param->getIdentifier()) {
3575 OS << Param->getIdentifier()->getName();
3576 continue;
3577 }
3578
3579 // There is no parameter name, which makes this tricky. Try to come up
3580 // with something useful that isn't too long.
3581 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3582 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3583 else if (NonTypeTemplateParmDecl *NTTP
3584 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3585 OS << NTTP->getType().getAsString(Policy);
3586 else
3587 OS << "template<...> class";
3588 }
3589
3590 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003591 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003592 }
3593
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003594 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003595 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3596 // If the type was explicitly written, use that.
3597 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003598 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003599
Benjamin Kramer9170e912013-02-22 15:46:01 +00003600 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003601 llvm::raw_svector_ostream OS(Str);
3602 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003603 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003604 ClassSpec->getTemplateArgs().data(),
3605 ClassSpec->getTemplateArgs().size(),
3606 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003607 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003608 }
3609
3610 return clang_getCursorSpelling(C);
3611}
3612
3613CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3614 switch (Kind) {
3615 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003616 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003617 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003618 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003619 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003620 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003621 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003622 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003624 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003626 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003628 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003630 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003632 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003633 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003634 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003636 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003638 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003639 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003640 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003642 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003643 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003644 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003646 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003648 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003650 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003652 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003654 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003656 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003658 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003660 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003662 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003664 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003666 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003668 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003670 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003672 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003743 case CXCursor_ObjCSelfExpr:
3744 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003861 case CXCursor_PackedAttr:
3862 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003910 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003911 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003912 return cxstring::createRef("OMPParallelDirective");
3913 case CXCursor_OMPSimdDirective:
3914 return cxstring::createRef("OMPSimdDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 }
3916
3917 llvm_unreachable("Unhandled CXCursorKind");
3918}
3919
3920struct GetCursorData {
3921 SourceLocation TokenBeginLoc;
3922 bool PointsAtMacroArgExpansion;
3923 bool VisitedObjCPropertyImplDecl;
3924 SourceLocation VisitedDeclaratorDeclStartLoc;
3925 CXCursor &BestCursor;
3926
3927 GetCursorData(SourceManager &SM,
3928 SourceLocation tokenBegin, CXCursor &outputCursor)
3929 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3930 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3931 VisitedObjCPropertyImplDecl = false;
3932 }
3933};
3934
3935static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3936 CXCursor parent,
3937 CXClientData client_data) {
3938 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3939 CXCursor *BestCursor = &Data->BestCursor;
3940
3941 // If we point inside a macro argument we should provide info of what the
3942 // token is so use the actual cursor, don't replace it with a macro expansion
3943 // cursor.
3944 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3945 return CXChildVisit_Recurse;
3946
3947 if (clang_isDeclaration(cursor.kind)) {
3948 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003949 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003950 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3951 if (MD->isImplicit())
3952 return CXChildVisit_Break;
3953
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003954 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003955 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3956 // Check that when we have multiple @class references in the same line,
3957 // that later ones do not override the previous ones.
3958 // If we have:
3959 // @class Foo, Bar;
3960 // source ranges for both start at '@', so 'Bar' will end up overriding
3961 // 'Foo' even though the cursor location was at 'Foo'.
3962 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3963 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003964 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3966 if (PrevID != ID &&
3967 !PrevID->isThisDeclarationADefinition() &&
3968 !ID->isThisDeclarationADefinition())
3969 return CXChildVisit_Break;
3970 }
3971
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003972 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3974 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3975 // Check that when we have multiple declarators in the same line,
3976 // that later ones do not override the previous ones.
3977 // If we have:
3978 // int Foo, Bar;
3979 // source ranges for both start at 'int', so 'Bar' will end up overriding
3980 // 'Foo' even though the cursor location was at 'Foo'.
3981 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3982 return CXChildVisit_Break;
3983 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3984
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003985 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3987 (void)PropImp;
3988 // Check that when we have multiple @synthesize in the same line,
3989 // that later ones do not override the previous ones.
3990 // If we have:
3991 // @synthesize Foo, Bar;
3992 // source ranges for both start at '@', so 'Bar' will end up overriding
3993 // 'Foo' even though the cursor location was at 'Foo'.
3994 if (Data->VisitedObjCPropertyImplDecl)
3995 return CXChildVisit_Break;
3996 Data->VisitedObjCPropertyImplDecl = true;
3997 }
3998 }
3999
4000 if (clang_isExpression(cursor.kind) &&
4001 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004002 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004003 // Avoid having the cursor of an expression replace the declaration cursor
4004 // when the expression source range overlaps the declaration range.
4005 // This can happen for C++ constructor expressions whose range generally
4006 // include the variable declaration, e.g.:
4007 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4008 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4009 D->getLocation() == Data->TokenBeginLoc)
4010 return CXChildVisit_Break;
4011 }
4012 }
4013
4014 // If our current best cursor is the construction of a temporary object,
4015 // don't replace that cursor with a type reference, because we want
4016 // clang_getCursor() to point at the constructor.
4017 if (clang_isExpression(BestCursor->kind) &&
4018 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4019 cursor.kind == CXCursor_TypeRef) {
4020 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4021 // as having the actual point on the type reference.
4022 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4023 return CXChildVisit_Recurse;
4024 }
4025
4026 *BestCursor = cursor;
4027 return CXChildVisit_Recurse;
4028}
4029
4030CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004031 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004032 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004033 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004034 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004035
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004036 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004037 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4038
4039 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4040 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4041
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004042 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 CXFile SearchFile;
4044 unsigned SearchLine, SearchColumn;
4045 CXFile ResultFile;
4046 unsigned ResultLine, ResultColumn;
4047 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4048 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4049 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4050
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004051 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4052 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004053 &ResultColumn, 0);
4054 SearchFileName = clang_getFileName(SearchFile);
4055 ResultFileName = clang_getFileName(ResultFile);
4056 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4057 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004058 *Log << llvm::format("(%s:%d:%d) = %s",
4059 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4060 clang_getCString(KindSpelling))
4061 << llvm::format("(%s:%d:%d):%s%s",
4062 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4063 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 clang_disposeString(SearchFileName);
4065 clang_disposeString(ResultFileName);
4066 clang_disposeString(KindSpelling);
4067 clang_disposeString(USR);
4068
4069 CXCursor Definition = clang_getCursorDefinition(Result);
4070 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4071 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4072 CXString DefinitionKindSpelling
4073 = clang_getCursorKindSpelling(Definition.kind);
4074 CXFile DefinitionFile;
4075 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004076 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 &DefinitionLine, &DefinitionColumn, 0);
4078 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004079 *Log << llvm::format(" -> %s(%s:%d:%d)",
4080 clang_getCString(DefinitionKindSpelling),
4081 clang_getCString(DefinitionFileName),
4082 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 clang_disposeString(DefinitionFileName);
4084 clang_disposeString(DefinitionKindSpelling);
4085 }
4086 }
4087
4088 return Result;
4089}
4090
4091CXCursor clang_getNullCursor(void) {
4092 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4093}
4094
4095unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004096 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4097 // can't set consistently. For example, when visiting a DeclStmt we will set
4098 // it but we don't set it on the result of clang_getCursorDefinition for
4099 // a reference of the same declaration.
4100 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4101 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4102 // to provide that kind of info.
4103 if (clang_isDeclaration(X.kind))
4104 X.data[1] = 0;
4105 if (clang_isDeclaration(Y.kind))
4106 Y.data[1] = 0;
4107
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 return X == Y;
4109}
4110
4111unsigned clang_hashCursor(CXCursor C) {
4112 unsigned Index = 0;
4113 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4114 Index = 1;
4115
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004116 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004117 std::make_pair(C.kind, C.data[Index]));
4118}
4119
4120unsigned clang_isInvalid(enum CXCursorKind K) {
4121 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4122}
4123
4124unsigned clang_isDeclaration(enum CXCursorKind K) {
4125 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4126 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4127}
4128
4129unsigned clang_isReference(enum CXCursorKind K) {
4130 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4131}
4132
4133unsigned clang_isExpression(enum CXCursorKind K) {
4134 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4135}
4136
4137unsigned clang_isStatement(enum CXCursorKind K) {
4138 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4139}
4140
4141unsigned clang_isAttribute(enum CXCursorKind K) {
4142 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4143}
4144
4145unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4146 return K == CXCursor_TranslationUnit;
4147}
4148
4149unsigned clang_isPreprocessing(enum CXCursorKind K) {
4150 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4151}
4152
4153unsigned clang_isUnexposed(enum CXCursorKind K) {
4154 switch (K) {
4155 case CXCursor_UnexposedDecl:
4156 case CXCursor_UnexposedExpr:
4157 case CXCursor_UnexposedStmt:
4158 case CXCursor_UnexposedAttr:
4159 return true;
4160 default:
4161 return false;
4162 }
4163}
4164
4165CXCursorKind clang_getCursorKind(CXCursor C) {
4166 return C.kind;
4167}
4168
4169CXSourceLocation clang_getCursorLocation(CXCursor C) {
4170 if (clang_isReference(C.kind)) {
4171 switch (C.kind) {
4172 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004173 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004174 = getCursorObjCSuperClassRef(C);
4175 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4176 }
4177
4178 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004179 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004180 = getCursorObjCProtocolRef(C);
4181 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4182 }
4183
4184 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004185 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 = getCursorObjCClassRef(C);
4187 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4188 }
4189
4190 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004191 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4193 }
4194
4195 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004196 std::pair<const TemplateDecl *, SourceLocation> P =
4197 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4199 }
4200
4201 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004202 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004203 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4204 }
4205
4206 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004207 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004208 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4209 }
4210
4211 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004212 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004213 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4214 }
4215
4216 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004217 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 if (!BaseSpec)
4219 return clang_getNullLocation();
4220
4221 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4222 return cxloc::translateSourceLocation(getCursorContext(C),
4223 TSInfo->getTypeLoc().getBeginLoc());
4224
4225 return cxloc::translateSourceLocation(getCursorContext(C),
4226 BaseSpec->getLocStart());
4227 }
4228
4229 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004230 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004231 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4232 }
4233
4234 case CXCursor_OverloadedDeclRef:
4235 return cxloc::translateSourceLocation(getCursorContext(C),
4236 getCursorOverloadedDeclRef(C).second);
4237
4238 default:
4239 // FIXME: Need a way to enumerate all non-reference cases.
4240 llvm_unreachable("Missed a reference kind");
4241 }
4242 }
4243
4244 if (clang_isExpression(C.kind))
4245 return cxloc::translateSourceLocation(getCursorContext(C),
4246 getLocationFromExpr(getCursorExpr(C)));
4247
4248 if (clang_isStatement(C.kind))
4249 return cxloc::translateSourceLocation(getCursorContext(C),
4250 getCursorStmt(C)->getLocStart());
4251
4252 if (C.kind == CXCursor_PreprocessingDirective) {
4253 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4254 return cxloc::translateSourceLocation(getCursorContext(C), L);
4255 }
4256
4257 if (C.kind == CXCursor_MacroExpansion) {
4258 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004259 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004260 return cxloc::translateSourceLocation(getCursorContext(C), L);
4261 }
4262
4263 if (C.kind == CXCursor_MacroDefinition) {
4264 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4265 return cxloc::translateSourceLocation(getCursorContext(C), L);
4266 }
4267
4268 if (C.kind == CXCursor_InclusionDirective) {
4269 SourceLocation L
4270 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4271 return cxloc::translateSourceLocation(getCursorContext(C), L);
4272 }
4273
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004274 if (clang_isAttribute(C.kind)) {
4275 SourceLocation L
4276 = cxcursor::getCursorAttr(C)->getLocation();
4277 return cxloc::translateSourceLocation(getCursorContext(C), L);
4278 }
4279
Guy Benyei11169dd2012-12-18 14:30:41 +00004280 if (!clang_isDeclaration(C.kind))
4281 return clang_getNullLocation();
4282
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004283 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004284 if (!D)
4285 return clang_getNullLocation();
4286
4287 SourceLocation Loc = D->getLocation();
4288 // FIXME: Multiple variables declared in a single declaration
4289 // currently lack the information needed to correctly determine their
4290 // ranges when accounting for the type-specifier. We use context
4291 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4292 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004293 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004294 if (!cxcursor::isFirstInDeclGroup(C))
4295 Loc = VD->getLocation();
4296 }
4297
4298 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004299 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004300 Loc = MD->getSelectorStartLoc();
4301
4302 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4303}
4304
4305} // end extern "C"
4306
4307CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4308 assert(TU);
4309
4310 // Guard against an invalid SourceLocation, or we may assert in one
4311 // of the following calls.
4312 if (SLoc.isInvalid())
4313 return clang_getNullCursor();
4314
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004315 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004316
4317 // Translate the given source location to make it point at the beginning of
4318 // the token under the cursor.
4319 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4320 CXXUnit->getASTContext().getLangOpts());
4321
4322 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4323 if (SLoc.isValid()) {
4324 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4325 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4326 /*VisitPreprocessorLast=*/true,
4327 /*VisitIncludedEntities=*/false,
4328 SourceLocation(SLoc));
4329 CursorVis.visitFileRegion();
4330 }
4331
4332 return Result;
4333}
4334
4335static SourceRange getRawCursorExtent(CXCursor C) {
4336 if (clang_isReference(C.kind)) {
4337 switch (C.kind) {
4338 case CXCursor_ObjCSuperClassRef:
4339 return getCursorObjCSuperClassRef(C).second;
4340
4341 case CXCursor_ObjCProtocolRef:
4342 return getCursorObjCProtocolRef(C).second;
4343
4344 case CXCursor_ObjCClassRef:
4345 return getCursorObjCClassRef(C).second;
4346
4347 case CXCursor_TypeRef:
4348 return getCursorTypeRef(C).second;
4349
4350 case CXCursor_TemplateRef:
4351 return getCursorTemplateRef(C).second;
4352
4353 case CXCursor_NamespaceRef:
4354 return getCursorNamespaceRef(C).second;
4355
4356 case CXCursor_MemberRef:
4357 return getCursorMemberRef(C).second;
4358
4359 case CXCursor_CXXBaseSpecifier:
4360 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4361
4362 case CXCursor_LabelRef:
4363 return getCursorLabelRef(C).second;
4364
4365 case CXCursor_OverloadedDeclRef:
4366 return getCursorOverloadedDeclRef(C).second;
4367
4368 case CXCursor_VariableRef:
4369 return getCursorVariableRef(C).second;
4370
4371 default:
4372 // FIXME: Need a way to enumerate all non-reference cases.
4373 llvm_unreachable("Missed a reference kind");
4374 }
4375 }
4376
4377 if (clang_isExpression(C.kind))
4378 return getCursorExpr(C)->getSourceRange();
4379
4380 if (clang_isStatement(C.kind))
4381 return getCursorStmt(C)->getSourceRange();
4382
4383 if (clang_isAttribute(C.kind))
4384 return getCursorAttr(C)->getRange();
4385
4386 if (C.kind == CXCursor_PreprocessingDirective)
4387 return cxcursor::getCursorPreprocessingDirective(C);
4388
4389 if (C.kind == CXCursor_MacroExpansion) {
4390 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004391 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004392 return TU->mapRangeFromPreamble(Range);
4393 }
4394
4395 if (C.kind == CXCursor_MacroDefinition) {
4396 ASTUnit *TU = getCursorASTUnit(C);
4397 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4398 return TU->mapRangeFromPreamble(Range);
4399 }
4400
4401 if (C.kind == CXCursor_InclusionDirective) {
4402 ASTUnit *TU = getCursorASTUnit(C);
4403 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4404 return TU->mapRangeFromPreamble(Range);
4405 }
4406
4407 if (C.kind == CXCursor_TranslationUnit) {
4408 ASTUnit *TU = getCursorASTUnit(C);
4409 FileID MainID = TU->getSourceManager().getMainFileID();
4410 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4411 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4412 return SourceRange(Start, End);
4413 }
4414
4415 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004416 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004417 if (!D)
4418 return SourceRange();
4419
4420 SourceRange R = D->getSourceRange();
4421 // FIXME: Multiple variables declared in a single declaration
4422 // currently lack the information needed to correctly determine their
4423 // ranges when accounting for the type-specifier. We use context
4424 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4425 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004426 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004427 if (!cxcursor::isFirstInDeclGroup(C))
4428 R.setBegin(VD->getLocation());
4429 }
4430 return R;
4431 }
4432 return SourceRange();
4433}
4434
4435/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4436/// the decl-specifier-seq for declarations.
4437static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4438 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004439 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004440 if (!D)
4441 return SourceRange();
4442
4443 SourceRange R = D->getSourceRange();
4444
4445 // Adjust the start of the location for declarations preceded by
4446 // declaration specifiers.
4447 SourceLocation StartLoc;
4448 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4449 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4450 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004451 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004452 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4453 StartLoc = TI->getTypeLoc().getLocStart();
4454 }
4455
4456 if (StartLoc.isValid() && R.getBegin().isValid() &&
4457 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4458 R.setBegin(StartLoc);
4459
4460 // FIXME: Multiple variables declared in a single declaration
4461 // currently lack the information needed to correctly determine their
4462 // ranges when accounting for the type-specifier. We use context
4463 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4464 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004465 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004466 if (!cxcursor::isFirstInDeclGroup(C))
4467 R.setBegin(VD->getLocation());
4468 }
4469
4470 return R;
4471 }
4472
4473 return getRawCursorExtent(C);
4474}
4475
4476extern "C" {
4477
4478CXSourceRange clang_getCursorExtent(CXCursor C) {
4479 SourceRange R = getRawCursorExtent(C);
4480 if (R.isInvalid())
4481 return clang_getNullRange();
4482
4483 return cxloc::translateSourceRange(getCursorContext(C), R);
4484}
4485
4486CXCursor clang_getCursorReferenced(CXCursor C) {
4487 if (clang_isInvalid(C.kind))
4488 return clang_getNullCursor();
4489
4490 CXTranslationUnit tu = getCursorTU(C);
4491 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004492 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004493 if (!D)
4494 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004495 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004496 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004497 if (const ObjCPropertyImplDecl *PropImpl =
4498 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004499 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4500 return MakeCXCursor(Property, tu);
4501
4502 return C;
4503 }
4504
4505 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004506 const Expr *E = getCursorExpr(C);
4507 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004508 if (D) {
4509 CXCursor declCursor = MakeCXCursor(D, tu);
4510 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4511 declCursor);
4512 return declCursor;
4513 }
4514
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004515 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004516 return MakeCursorOverloadedDeclRef(Ovl, tu);
4517
4518 return clang_getNullCursor();
4519 }
4520
4521 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004522 const Stmt *S = getCursorStmt(C);
4523 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004524 if (LabelDecl *label = Goto->getLabel())
4525 if (LabelStmt *labelS = label->getStmt())
4526 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4527
4528 return clang_getNullCursor();
4529 }
4530
4531 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004532 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004533 return MakeMacroDefinitionCursor(Def, tu);
4534 }
4535
4536 if (!clang_isReference(C.kind))
4537 return clang_getNullCursor();
4538
4539 switch (C.kind) {
4540 case CXCursor_ObjCSuperClassRef:
4541 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4542
4543 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004544 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4545 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004546 return MakeCXCursor(Def, tu);
4547
4548 return MakeCXCursor(Prot, tu);
4549 }
4550
4551 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004552 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4553 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004554 return MakeCXCursor(Def, tu);
4555
4556 return MakeCXCursor(Class, tu);
4557 }
4558
4559 case CXCursor_TypeRef:
4560 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4561
4562 case CXCursor_TemplateRef:
4563 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4564
4565 case CXCursor_NamespaceRef:
4566 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4567
4568 case CXCursor_MemberRef:
4569 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4570
4571 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004572 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004573 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4574 tu ));
4575 }
4576
4577 case CXCursor_LabelRef:
4578 // FIXME: We end up faking the "parent" declaration here because we
4579 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004580 return MakeCXCursor(getCursorLabelRef(C).first,
4581 cxtu::getASTUnit(tu)->getASTContext()
4582 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004583 tu);
4584
4585 case CXCursor_OverloadedDeclRef:
4586 return C;
4587
4588 case CXCursor_VariableRef:
4589 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4590
4591 default:
4592 // We would prefer to enumerate all non-reference cursor kinds here.
4593 llvm_unreachable("Unhandled reference cursor kind");
4594 }
4595}
4596
4597CXCursor clang_getCursorDefinition(CXCursor C) {
4598 if (clang_isInvalid(C.kind))
4599 return clang_getNullCursor();
4600
4601 CXTranslationUnit TU = getCursorTU(C);
4602
4603 bool WasReference = false;
4604 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4605 C = clang_getCursorReferenced(C);
4606 WasReference = true;
4607 }
4608
4609 if (C.kind == CXCursor_MacroExpansion)
4610 return clang_getCursorReferenced(C);
4611
4612 if (!clang_isDeclaration(C.kind))
4613 return clang_getNullCursor();
4614
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004615 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004616 if (!D)
4617 return clang_getNullCursor();
4618
4619 switch (D->getKind()) {
4620 // Declaration kinds that don't really separate the notions of
4621 // declaration and definition.
4622 case Decl::Namespace:
4623 case Decl::Typedef:
4624 case Decl::TypeAlias:
4625 case Decl::TypeAliasTemplate:
4626 case Decl::TemplateTypeParm:
4627 case Decl::EnumConstant:
4628 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004629 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004630 case Decl::IndirectField:
4631 case Decl::ObjCIvar:
4632 case Decl::ObjCAtDefsField:
4633 case Decl::ImplicitParam:
4634 case Decl::ParmVar:
4635 case Decl::NonTypeTemplateParm:
4636 case Decl::TemplateTemplateParm:
4637 case Decl::ObjCCategoryImpl:
4638 case Decl::ObjCImplementation:
4639 case Decl::AccessSpec:
4640 case Decl::LinkageSpec:
4641 case Decl::ObjCPropertyImpl:
4642 case Decl::FileScopeAsm:
4643 case Decl::StaticAssert:
4644 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004645 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004646 case Decl::Label: // FIXME: Is this right??
4647 case Decl::ClassScopeFunctionSpecialization:
4648 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004649 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004650 return C;
4651
4652 // Declaration kinds that don't make any sense here, but are
4653 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004654 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004655 case Decl::TranslationUnit:
4656 break;
4657
4658 // Declaration kinds for which the definition is not resolvable.
4659 case Decl::UnresolvedUsingTypename:
4660 case Decl::UnresolvedUsingValue:
4661 break;
4662
4663 case Decl::UsingDirective:
4664 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4665 TU);
4666
4667 case Decl::NamespaceAlias:
4668 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4669
4670 case Decl::Enum:
4671 case Decl::Record:
4672 case Decl::CXXRecord:
4673 case Decl::ClassTemplateSpecialization:
4674 case Decl::ClassTemplatePartialSpecialization:
4675 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4676 return MakeCXCursor(Def, TU);
4677 return clang_getNullCursor();
4678
4679 case Decl::Function:
4680 case Decl::CXXMethod:
4681 case Decl::CXXConstructor:
4682 case Decl::CXXDestructor:
4683 case Decl::CXXConversion: {
4684 const FunctionDecl *Def = 0;
4685 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004686 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004687 return clang_getNullCursor();
4688 }
4689
Larisse Voufo39a1e502013-08-06 01:03:05 +00004690 case Decl::Var:
4691 case Decl::VarTemplateSpecialization:
4692 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004693 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004694 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004695 return MakeCXCursor(Def, TU);
4696 return clang_getNullCursor();
4697 }
4698
4699 case Decl::FunctionTemplate: {
4700 const FunctionDecl *Def = 0;
4701 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4702 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4703 return clang_getNullCursor();
4704 }
4705
4706 case Decl::ClassTemplate: {
4707 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4708 ->getDefinition())
4709 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4710 TU);
4711 return clang_getNullCursor();
4712 }
4713
Larisse Voufo39a1e502013-08-06 01:03:05 +00004714 case Decl::VarTemplate: {
4715 if (VarDecl *Def =
4716 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4717 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4718 return clang_getNullCursor();
4719 }
4720
Guy Benyei11169dd2012-12-18 14:30:41 +00004721 case Decl::Using:
4722 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4723 D->getLocation(), TU);
4724
4725 case Decl::UsingShadow:
4726 return clang_getCursorDefinition(
4727 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4728 TU));
4729
4730 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004731 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004732 if (Method->isThisDeclarationADefinition())
4733 return C;
4734
4735 // Dig out the method definition in the associated
4736 // @implementation, if we have it.
4737 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004738 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004739 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4740 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4741 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4742 Method->isInstanceMethod()))
4743 if (Def->isThisDeclarationADefinition())
4744 return MakeCXCursor(Def, TU);
4745
4746 return clang_getNullCursor();
4747 }
4748
4749 case Decl::ObjCCategory:
4750 if (ObjCCategoryImplDecl *Impl
4751 = cast<ObjCCategoryDecl>(D)->getImplementation())
4752 return MakeCXCursor(Impl, TU);
4753 return clang_getNullCursor();
4754
4755 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004756 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004757 return MakeCXCursor(Def, TU);
4758 return clang_getNullCursor();
4759
4760 case Decl::ObjCInterface: {
4761 // There are two notions of a "definition" for an Objective-C
4762 // class: the interface and its implementation. When we resolved a
4763 // reference to an Objective-C class, produce the @interface as
4764 // the definition; when we were provided with the interface,
4765 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004766 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004767 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004768 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004769 return MakeCXCursor(Def, TU);
4770 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4771 return MakeCXCursor(Impl, TU);
4772 return clang_getNullCursor();
4773 }
4774
4775 case Decl::ObjCProperty:
4776 // FIXME: We don't really know where to find the
4777 // ObjCPropertyImplDecls that implement this property.
4778 return clang_getNullCursor();
4779
4780 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004781 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004782 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004783 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004784 return MakeCXCursor(Def, TU);
4785
4786 return clang_getNullCursor();
4787
4788 case Decl::Friend:
4789 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4790 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4791 return clang_getNullCursor();
4792
4793 case Decl::FriendTemplate:
4794 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4795 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4796 return clang_getNullCursor();
4797 }
4798
4799 return clang_getNullCursor();
4800}
4801
4802unsigned clang_isCursorDefinition(CXCursor C) {
4803 if (!clang_isDeclaration(C.kind))
4804 return 0;
4805
4806 return clang_getCursorDefinition(C) == C;
4807}
4808
4809CXCursor clang_getCanonicalCursor(CXCursor C) {
4810 if (!clang_isDeclaration(C.kind))
4811 return C;
4812
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004813 if (const Decl *D = getCursorDecl(C)) {
4814 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004815 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4816 return MakeCXCursor(CatD, getCursorTU(C));
4817
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004818 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4819 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004820 return MakeCXCursor(IFD, getCursorTU(C));
4821
4822 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4823 }
4824
4825 return C;
4826}
4827
4828int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4829 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4830}
4831
4832unsigned clang_getNumOverloadedDecls(CXCursor C) {
4833 if (C.kind != CXCursor_OverloadedDeclRef)
4834 return 0;
4835
4836 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004837 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004838 return E->getNumDecls();
4839
4840 if (OverloadedTemplateStorage *S
4841 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4842 return S->size();
4843
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004844 const Decl *D = Storage.get<const Decl *>();
4845 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004846 return Using->shadow_size();
4847
4848 return 0;
4849}
4850
4851CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4852 if (cursor.kind != CXCursor_OverloadedDeclRef)
4853 return clang_getNullCursor();
4854
4855 if (index >= clang_getNumOverloadedDecls(cursor))
4856 return clang_getNullCursor();
4857
4858 CXTranslationUnit TU = getCursorTU(cursor);
4859 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004860 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004861 return MakeCXCursor(E->decls_begin()[index], TU);
4862
4863 if (OverloadedTemplateStorage *S
4864 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4865 return MakeCXCursor(S->begin()[index], TU);
4866
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004867 const Decl *D = Storage.get<const Decl *>();
4868 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004869 // FIXME: This is, unfortunately, linear time.
4870 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4871 std::advance(Pos, index);
4872 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4873 }
4874
4875 return clang_getNullCursor();
4876}
4877
4878void clang_getDefinitionSpellingAndExtent(CXCursor C,
4879 const char **startBuf,
4880 const char **endBuf,
4881 unsigned *startLine,
4882 unsigned *startColumn,
4883 unsigned *endLine,
4884 unsigned *endColumn) {
4885 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004886 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004887 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4888
4889 SourceManager &SM = FD->getASTContext().getSourceManager();
4890 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4891 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4892 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4893 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4894 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4895 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4896}
4897
4898
4899CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4900 unsigned PieceIndex) {
4901 RefNamePieces Pieces;
4902
4903 switch (C.kind) {
4904 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004905 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004906 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4907 E->getQualifierLoc().getSourceRange());
4908 break;
4909
4910 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004911 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004912 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4913 E->getQualifierLoc().getSourceRange(),
4914 E->getOptionalExplicitTemplateArgs());
4915 break;
4916
4917 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004918 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004919 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004920 const Expr *Callee = OCE->getCallee();
4921 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004922 Callee = ICE->getSubExpr();
4923
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004924 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004925 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4926 DRE->getQualifierLoc().getSourceRange());
4927 }
4928 break;
4929
4930 default:
4931 break;
4932 }
4933
4934 if (Pieces.empty()) {
4935 if (PieceIndex == 0)
4936 return clang_getCursorExtent(C);
4937 } else if (PieceIndex < Pieces.size()) {
4938 SourceRange R = Pieces[PieceIndex];
4939 if (R.isValid())
4940 return cxloc::translateSourceRange(getCursorContext(C), R);
4941 }
4942
4943 return clang_getNullRange();
4944}
4945
4946void clang_enableStackTraces(void) {
4947 llvm::sys::PrintStackTraceOnErrorSignal();
4948}
4949
4950void clang_executeOnThread(void (*fn)(void*), void *user_data,
4951 unsigned stack_size) {
4952 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4953}
4954
4955} // end: extern "C"
4956
4957//===----------------------------------------------------------------------===//
4958// Token-based Operations.
4959//===----------------------------------------------------------------------===//
4960
4961/* CXToken layout:
4962 * int_data[0]: a CXTokenKind
4963 * int_data[1]: starting token location
4964 * int_data[2]: token length
4965 * int_data[3]: reserved
4966 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4967 * otherwise unused.
4968 */
4969extern "C" {
4970
4971CXTokenKind clang_getTokenKind(CXToken CXTok) {
4972 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4973}
4974
4975CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4976 switch (clang_getTokenKind(CXTok)) {
4977 case CXToken_Identifier:
4978 case CXToken_Keyword:
4979 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004980 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004981 ->getNameStart());
4982
4983 case CXToken_Literal: {
4984 // We have stashed the starting pointer in the ptr_data field. Use it.
4985 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004986 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004987 }
4988
4989 case CXToken_Punctuation:
4990 case CXToken_Comment:
4991 break;
4992 }
4993
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004994 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004995 LOG_BAD_TU(TU);
4996 return cxstring::createEmpty();
4997 }
4998
Guy Benyei11169dd2012-12-18 14:30:41 +00004999 // We have to find the starting buffer pointer the hard way, by
5000 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005001 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005002 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005003 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005004
5005 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5006 std::pair<FileID, unsigned> LocInfo
5007 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5008 bool Invalid = false;
5009 StringRef Buffer
5010 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5011 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005012 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005013
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005014 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005015}
5016
5017CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005018 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005019 LOG_BAD_TU(TU);
5020 return clang_getNullLocation();
5021 }
5022
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005023 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005024 if (!CXXUnit)
5025 return clang_getNullLocation();
5026
5027 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5028 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5029}
5030
5031CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005032 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005033 LOG_BAD_TU(TU);
5034 return clang_getNullRange();
5035 }
5036
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005037 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005038 if (!CXXUnit)
5039 return clang_getNullRange();
5040
5041 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5042 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5043}
5044
5045static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5046 SmallVectorImpl<CXToken> &CXTokens) {
5047 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5048 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005049 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005050 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005051 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005052
5053 // Cannot tokenize across files.
5054 if (BeginLocInfo.first != EndLocInfo.first)
5055 return;
5056
5057 // Create a lexer
5058 bool Invalid = false;
5059 StringRef Buffer
5060 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5061 if (Invalid)
5062 return;
5063
5064 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5065 CXXUnit->getASTContext().getLangOpts(),
5066 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5067 Lex.SetCommentRetentionState(true);
5068
5069 // Lex tokens until we hit the end of the range.
5070 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5071 Token Tok;
5072 bool previousWasAt = false;
5073 do {
5074 // Lex the next token
5075 Lex.LexFromRawLexer(Tok);
5076 if (Tok.is(tok::eof))
5077 break;
5078
5079 // Initialize the CXToken.
5080 CXToken CXTok;
5081
5082 // - Common fields
5083 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5084 CXTok.int_data[2] = Tok.getLength();
5085 CXTok.int_data[3] = 0;
5086
5087 // - Kind-specific fields
5088 if (Tok.isLiteral()) {
5089 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005090 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005091 } else if (Tok.is(tok::raw_identifier)) {
5092 // Lookup the identifier to determine whether we have a keyword.
5093 IdentifierInfo *II
5094 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5095
5096 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5097 CXTok.int_data[0] = CXToken_Keyword;
5098 }
5099 else {
5100 CXTok.int_data[0] = Tok.is(tok::identifier)
5101 ? CXToken_Identifier
5102 : CXToken_Keyword;
5103 }
5104 CXTok.ptr_data = II;
5105 } else if (Tok.is(tok::comment)) {
5106 CXTok.int_data[0] = CXToken_Comment;
5107 CXTok.ptr_data = 0;
5108 } else {
5109 CXTok.int_data[0] = CXToken_Punctuation;
5110 CXTok.ptr_data = 0;
5111 }
5112 CXTokens.push_back(CXTok);
5113 previousWasAt = Tok.is(tok::at);
5114 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5115}
5116
5117void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5118 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005119 LOG_FUNC_SECTION {
5120 *Log << TU << ' ' << Range;
5121 }
5122
Guy Benyei11169dd2012-12-18 14:30:41 +00005123 if (Tokens)
5124 *Tokens = 0;
5125 if (NumTokens)
5126 *NumTokens = 0;
5127
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005128 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005129 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005130 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005131 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005132
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005133 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005134 if (!CXXUnit || !Tokens || !NumTokens)
5135 return;
5136
5137 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5138
5139 SourceRange R = cxloc::translateCXSourceRange(Range);
5140 if (R.isInvalid())
5141 return;
5142
5143 SmallVector<CXToken, 32> CXTokens;
5144 getTokens(CXXUnit, R, CXTokens);
5145
5146 if (CXTokens.empty())
5147 return;
5148
5149 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5150 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5151 *NumTokens = CXTokens.size();
5152}
5153
5154void clang_disposeTokens(CXTranslationUnit TU,
5155 CXToken *Tokens, unsigned NumTokens) {
5156 free(Tokens);
5157}
5158
5159} // end: extern "C"
5160
5161//===----------------------------------------------------------------------===//
5162// Token annotation APIs.
5163//===----------------------------------------------------------------------===//
5164
Guy Benyei11169dd2012-12-18 14:30:41 +00005165static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5166 CXCursor parent,
5167 CXClientData client_data);
5168static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5169 CXClientData client_data);
5170
5171namespace {
5172class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005173 CXToken *Tokens;
5174 CXCursor *Cursors;
5175 unsigned NumTokens;
5176 unsigned TokIdx;
5177 unsigned PreprocessingTokIdx;
5178 CursorVisitor AnnotateVis;
5179 SourceManager &SrcMgr;
5180 bool HasContextSensitiveKeywords;
5181
5182 struct PostChildrenInfo {
5183 CXCursor Cursor;
5184 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005185 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005186 unsigned BeforeChildrenTokenIdx;
5187 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005188 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005189
5190 CXToken &getTok(unsigned Idx) {
5191 assert(Idx < NumTokens);
5192 return Tokens[Idx];
5193 }
5194 const CXToken &getTok(unsigned Idx) const {
5195 assert(Idx < NumTokens);
5196 return Tokens[Idx];
5197 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005198 bool MoreTokens() const { return TokIdx < NumTokens; }
5199 unsigned NextToken() const { return TokIdx; }
5200 void AdvanceToken() { ++TokIdx; }
5201 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005202 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005203 }
5204 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005205 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005206 }
5207 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005208 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005209 }
5210
5211 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005212 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005213 SourceRange);
5214
5215public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005216 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005217 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005218 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005219 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005220 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005221 AnnotateTokensVisitor, this,
5222 /*VisitPreprocessorLast=*/true,
5223 /*VisitIncludedEntities=*/false,
5224 RegionOfInterest,
5225 /*VisitDeclsOnly=*/false,
5226 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005227 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 HasContextSensitiveKeywords(false) { }
5229
5230 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5231 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5232 bool postVisitChildren(CXCursor cursor);
5233 void AnnotateTokens();
5234
5235 /// \brief Determine whether the annotator saw any cursors that have
5236 /// context-sensitive keywords.
5237 bool hasContextSensitiveKeywords() const {
5238 return HasContextSensitiveKeywords;
5239 }
5240
5241 ~AnnotateTokensWorker() {
5242 assert(PostChildrenInfos.empty());
5243 }
5244};
5245}
5246
5247void AnnotateTokensWorker::AnnotateTokens() {
5248 // Walk the AST within the region of interest, annotating tokens
5249 // along the way.
5250 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005251}
Guy Benyei11169dd2012-12-18 14:30:41 +00005252
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005253static inline void updateCursorAnnotation(CXCursor &Cursor,
5254 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005255 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005256 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005257 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005258}
5259
5260/// \brief It annotates and advances tokens with a cursor until the comparison
5261//// between the cursor location and the source range is the same as
5262/// \arg compResult.
5263///
5264/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5265/// Pass RangeOverlap to annotate tokens inside a range.
5266void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5267 RangeComparisonResult compResult,
5268 SourceRange range) {
5269 while (MoreTokens()) {
5270 const unsigned I = NextToken();
5271 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005272 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5273 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005274
5275 SourceLocation TokLoc = GetTokenLoc(I);
5276 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005277 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005278 AdvanceToken();
5279 continue;
5280 }
5281 break;
5282 }
5283}
5284
5285/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005286/// \returns true if it advanced beyond all macro tokens, false otherwise.
5287bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005288 CXCursor updateC,
5289 RangeComparisonResult compResult,
5290 SourceRange range) {
5291 assert(MoreTokens());
5292 assert(isFunctionMacroToken(NextToken()) &&
5293 "Should be called only for macro arg tokens");
5294
5295 // This works differently than annotateAndAdvanceTokens; because expanded
5296 // macro arguments can have arbitrary translation-unit source order, we do not
5297 // advance the token index one by one until a token fails the range test.
5298 // We only advance once past all of the macro arg tokens if all of them
5299 // pass the range test. If one of them fails we keep the token index pointing
5300 // at the start of the macro arg tokens so that the failing token will be
5301 // annotated by a subsequent annotation try.
5302
5303 bool atLeastOneCompFail = false;
5304
5305 unsigned I = NextToken();
5306 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5307 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5308 if (TokLoc.isFileID())
5309 continue; // not macro arg token, it's parens or comma.
5310 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5311 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5312 Cursors[I] = updateC;
5313 } else
5314 atLeastOneCompFail = true;
5315 }
5316
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005317 if (atLeastOneCompFail)
5318 return false;
5319
5320 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5321 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005322}
5323
5324enum CXChildVisitResult
5325AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005326 SourceRange cursorRange = getRawCursorExtent(cursor);
5327 if (cursorRange.isInvalid())
5328 return CXChildVisit_Recurse;
5329
5330 if (!HasContextSensitiveKeywords) {
5331 // Objective-C properties can have context-sensitive keywords.
5332 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005333 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005334 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5335 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5336 }
5337 // Objective-C methods can have context-sensitive keywords.
5338 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5339 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005340 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005341 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5342 if (Method->getObjCDeclQualifier())
5343 HasContextSensitiveKeywords = true;
5344 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005345 for (const auto *P : Method->params()) {
5346 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005347 HasContextSensitiveKeywords = true;
5348 break;
5349 }
5350 }
5351 }
5352 }
5353 }
5354 // C++ methods can have context-sensitive keywords.
5355 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005356 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005357 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5358 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5359 HasContextSensitiveKeywords = true;
5360 }
5361 }
5362 // C++ classes can have context-sensitive keywords.
5363 else if (cursor.kind == CXCursor_StructDecl ||
5364 cursor.kind == CXCursor_ClassDecl ||
5365 cursor.kind == CXCursor_ClassTemplate ||
5366 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005367 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005368 if (D->hasAttr<FinalAttr>())
5369 HasContextSensitiveKeywords = true;
5370 }
5371 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005372
5373 // Don't override a property annotation with its getter/setter method.
5374 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5375 parent.kind == CXCursor_ObjCPropertyDecl)
5376 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005377
5378 if (clang_isPreprocessing(cursor.kind)) {
5379 // Items in the preprocessing record are kept separate from items in
5380 // declarations, so we keep a separate token index.
5381 unsigned SavedTokIdx = TokIdx;
5382 TokIdx = PreprocessingTokIdx;
5383
5384 // Skip tokens up until we catch up to the beginning of the preprocessing
5385 // entry.
5386 while (MoreTokens()) {
5387 const unsigned I = NextToken();
5388 SourceLocation TokLoc = GetTokenLoc(I);
5389 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5390 case RangeBefore:
5391 AdvanceToken();
5392 continue;
5393 case RangeAfter:
5394 case RangeOverlap:
5395 break;
5396 }
5397 break;
5398 }
5399
5400 // Look at all of the tokens within this range.
5401 while (MoreTokens()) {
5402 const unsigned I = NextToken();
5403 SourceLocation TokLoc = GetTokenLoc(I);
5404 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5405 case RangeBefore:
5406 llvm_unreachable("Infeasible");
5407 case RangeAfter:
5408 break;
5409 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005410 // For macro expansions, just note where the beginning of the macro
5411 // expansion occurs.
5412 if (cursor.kind == CXCursor_MacroExpansion) {
5413 if (TokLoc == cursorRange.getBegin())
5414 Cursors[I] = cursor;
5415 AdvanceToken();
5416 break;
5417 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005418 // We may have already annotated macro names inside macro definitions.
5419 if (Cursors[I].kind != CXCursor_MacroExpansion)
5420 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005421 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005422 continue;
5423 }
5424 break;
5425 }
5426
5427 // Save the preprocessing token index; restore the non-preprocessing
5428 // token index.
5429 PreprocessingTokIdx = TokIdx;
5430 TokIdx = SavedTokIdx;
5431 return CXChildVisit_Recurse;
5432 }
5433
5434 if (cursorRange.isInvalid())
5435 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005436
5437 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005438 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005439 const enum CXCursorKind K = clang_getCursorKind(parent);
5440 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005441 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5442 // Attributes are annotated out-of-order, skip tokens until we reach it.
5443 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005444 ? clang_getNullCursor() : parent;
5445
5446 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5447
5448 // Avoid having the cursor of an expression "overwrite" the annotation of the
5449 // variable declaration that it belongs to.
5450 // This can happen for C++ constructor expressions whose range generally
5451 // include the variable declaration, e.g.:
5452 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005453 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005454 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005455 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005456 const unsigned I = NextToken();
5457 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5458 E->getLocStart() == D->getLocation() &&
5459 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005460 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005461 AdvanceToken();
5462 }
5463 }
5464 }
5465
5466 // Before recursing into the children keep some state that we are going
5467 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5468 // extra work after the child nodes are visited.
5469 // Note that we don't call VisitChildren here to avoid traversing statements
5470 // code-recursively which can blow the stack.
5471
5472 PostChildrenInfo Info;
5473 Info.Cursor = cursor;
5474 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005475 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005476 Info.BeforeChildrenTokenIdx = NextToken();
5477 PostChildrenInfos.push_back(Info);
5478
5479 return CXChildVisit_Recurse;
5480}
5481
5482bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5483 if (PostChildrenInfos.empty())
5484 return false;
5485 const PostChildrenInfo &Info = PostChildrenInfos.back();
5486 if (!clang_equalCursors(Info.Cursor, cursor))
5487 return false;
5488
5489 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5490 const unsigned AfterChildren = NextToken();
5491 SourceRange cursorRange = Info.CursorRange;
5492
5493 // Scan the tokens that are at the end of the cursor, but are not captured
5494 // but the child cursors.
5495 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5496
5497 // Scan the tokens that are at the beginning of the cursor, but are not
5498 // capture by the child cursors.
5499 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5500 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5501 break;
5502
5503 Cursors[I] = cursor;
5504 }
5505
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005506 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5507 // encountered the attribute cursor.
5508 if (clang_isAttribute(cursor.kind))
5509 TokIdx = Info.BeforeReachingCursorIdx;
5510
Guy Benyei11169dd2012-12-18 14:30:41 +00005511 PostChildrenInfos.pop_back();
5512 return false;
5513}
5514
5515static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5516 CXCursor parent,
5517 CXClientData client_data) {
5518 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5519}
5520
5521static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5522 CXClientData client_data) {
5523 return static_cast<AnnotateTokensWorker*>(client_data)->
5524 postVisitChildren(cursor);
5525}
5526
5527namespace {
5528
5529/// \brief Uses the macro expansions in the preprocessing record to find
5530/// and mark tokens that are macro arguments. This info is used by the
5531/// AnnotateTokensWorker.
5532class MarkMacroArgTokensVisitor {
5533 SourceManager &SM;
5534 CXToken *Tokens;
5535 unsigned NumTokens;
5536 unsigned CurIdx;
5537
5538public:
5539 MarkMacroArgTokensVisitor(SourceManager &SM,
5540 CXToken *tokens, unsigned numTokens)
5541 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5542
5543 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5544 if (cursor.kind != CXCursor_MacroExpansion)
5545 return CXChildVisit_Continue;
5546
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005547 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005548 if (macroRange.getBegin() == macroRange.getEnd())
5549 return CXChildVisit_Continue; // it's not a function macro.
5550
5551 for (; CurIdx < NumTokens; ++CurIdx) {
5552 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5553 macroRange.getBegin()))
5554 break;
5555 }
5556
5557 if (CurIdx == NumTokens)
5558 return CXChildVisit_Break;
5559
5560 for (; CurIdx < NumTokens; ++CurIdx) {
5561 SourceLocation tokLoc = getTokenLoc(CurIdx);
5562 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5563 break;
5564
5565 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5566 }
5567
5568 if (CurIdx == NumTokens)
5569 return CXChildVisit_Break;
5570
5571 return CXChildVisit_Continue;
5572 }
5573
5574private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005575 CXToken &getTok(unsigned Idx) {
5576 assert(Idx < NumTokens);
5577 return Tokens[Idx];
5578 }
5579 const CXToken &getTok(unsigned Idx) const {
5580 assert(Idx < NumTokens);
5581 return Tokens[Idx];
5582 }
5583
Guy Benyei11169dd2012-12-18 14:30:41 +00005584 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005585 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005586 }
5587
5588 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5589 // The third field is reserved and currently not used. Use it here
5590 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005591 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005592 }
5593};
5594
5595} // end anonymous namespace
5596
5597static CXChildVisitResult
5598MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5599 CXClientData client_data) {
5600 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5601 parent);
5602}
5603
5604namespace {
5605 struct clang_annotateTokens_Data {
5606 CXTranslationUnit TU;
5607 ASTUnit *CXXUnit;
5608 CXToken *Tokens;
5609 unsigned NumTokens;
5610 CXCursor *Cursors;
5611 };
5612}
5613
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005614/// \brief Used by \c annotatePreprocessorTokens.
5615/// \returns true if lexing was finished, false otherwise.
5616static bool lexNext(Lexer &Lex, Token &Tok,
5617 unsigned &NextIdx, unsigned NumTokens) {
5618 if (NextIdx >= NumTokens)
5619 return true;
5620
5621 ++NextIdx;
5622 Lex.LexFromRawLexer(Tok);
5623 if (Tok.is(tok::eof))
5624 return true;
5625
5626 return false;
5627}
5628
Guy Benyei11169dd2012-12-18 14:30:41 +00005629static void annotatePreprocessorTokens(CXTranslationUnit TU,
5630 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005631 CXCursor *Cursors,
5632 CXToken *Tokens,
5633 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005634 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005635
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005636 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005637 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5638 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005639 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005640 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005641 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005642
5643 if (BeginLocInfo.first != EndLocInfo.first)
5644 return;
5645
5646 StringRef Buffer;
5647 bool Invalid = false;
5648 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5649 if (Buffer.empty() || Invalid)
5650 return;
5651
5652 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5653 CXXUnit->getASTContext().getLangOpts(),
5654 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5655 Buffer.end());
5656 Lex.SetCommentRetentionState(true);
5657
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005658 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005659 // Lex tokens in raw mode until we hit the end of the range, to avoid
5660 // entering #includes or expanding macros.
5661 while (true) {
5662 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005663 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5664 break;
5665 unsigned TokIdx = NextIdx-1;
5666 assert(Tok.getLocation() ==
5667 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005668
5669 reprocess:
5670 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005671 // We have found a preprocessing directive. Annotate the tokens
5672 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005673 //
5674 // FIXME: Some simple tests here could identify macro definitions and
5675 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005676
5677 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005678 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5679 break;
5680
5681 MacroInfo *MI = 0;
5682 if (Tok.is(tok::raw_identifier) &&
5683 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5684 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5685 break;
5686
5687 if (Tok.is(tok::raw_identifier)) {
5688 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5689 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5690 SourceLocation MappedTokLoc =
5691 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5692 MI = getMacroInfo(II, MappedTokLoc, TU);
5693 }
5694 }
5695
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005696 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005697 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005698 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5699 finished = true;
5700 break;
5701 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005702 // If we are in a macro definition, check if the token was ever a
5703 // macro name and annotate it if that's the case.
5704 if (MI) {
5705 SourceLocation SaveLoc = Tok.getLocation();
5706 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5707 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5708 Tok.setLocation(SaveLoc);
5709 if (MacroDef)
5710 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5711 Tok.getLocation(), TU);
5712 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005713 } while (!Tok.isAtStartOfLine());
5714
5715 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5716 assert(TokIdx <= LastIdx);
5717 SourceLocation EndLoc =
5718 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5719 CXCursor Cursor =
5720 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5721
5722 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005723 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005724
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005725 if (finished)
5726 break;
5727 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005728 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005729 }
5730}
5731
5732// This gets run a separate thread to avoid stack blowout.
5733static void clang_annotateTokensImpl(void *UserData) {
5734 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5735 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5736 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5737 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5738 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5739
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005740 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005741 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5742 setThreadBackgroundPriority();
5743
5744 // Determine the region of interest, which contains all of the tokens.
5745 SourceRange RegionOfInterest;
5746 RegionOfInterest.setBegin(
5747 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5748 RegionOfInterest.setEnd(
5749 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5750 Tokens[NumTokens-1])));
5751
Guy Benyei11169dd2012-12-18 14:30:41 +00005752 // Relex the tokens within the source range to look for preprocessing
5753 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005754 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005755
5756 // If begin location points inside a macro argument, set it to the expansion
5757 // location so we can have the full context when annotating semantically.
5758 {
5759 SourceManager &SM = CXXUnit->getSourceManager();
5760 SourceLocation Loc =
5761 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5762 if (Loc.isMacroID())
5763 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5764 }
5765
Guy Benyei11169dd2012-12-18 14:30:41 +00005766 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5767 // Search and mark tokens that are macro argument expansions.
5768 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5769 Tokens, NumTokens);
5770 CursorVisitor MacroArgMarker(TU,
5771 MarkMacroArgTokensVisitorDelegate, &Visitor,
5772 /*VisitPreprocessorLast=*/true,
5773 /*VisitIncludedEntities=*/false,
5774 RegionOfInterest);
5775 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5776 }
5777
5778 // Annotate all of the source locations in the region of interest that map to
5779 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005780 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005781
5782 // FIXME: We use a ridiculous stack size here because the data-recursion
5783 // algorithm uses a large stack frame than the non-data recursive version,
5784 // and AnnotationTokensWorker currently transforms the data-recursion
5785 // algorithm back into a traditional recursion by explicitly calling
5786 // VisitChildren(). We will need to remove this explicit recursive call.
5787 W.AnnotateTokens();
5788
5789 // If we ran into any entities that involve context-sensitive keywords,
5790 // take another pass through the tokens to mark them as such.
5791 if (W.hasContextSensitiveKeywords()) {
5792 for (unsigned I = 0; I != NumTokens; ++I) {
5793 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5794 continue;
5795
5796 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5797 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005798 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005799 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5800 if (Property->getPropertyAttributesAsWritten() != 0 &&
5801 llvm::StringSwitch<bool>(II->getName())
5802 .Case("readonly", true)
5803 .Case("assign", true)
5804 .Case("unsafe_unretained", true)
5805 .Case("readwrite", true)
5806 .Case("retain", true)
5807 .Case("copy", true)
5808 .Case("nonatomic", true)
5809 .Case("atomic", true)
5810 .Case("getter", true)
5811 .Case("setter", true)
5812 .Case("strong", true)
5813 .Case("weak", true)
5814 .Default(false))
5815 Tokens[I].int_data[0] = CXToken_Keyword;
5816 }
5817 continue;
5818 }
5819
5820 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5821 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5822 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5823 if (llvm::StringSwitch<bool>(II->getName())
5824 .Case("in", true)
5825 .Case("out", true)
5826 .Case("inout", true)
5827 .Case("oneway", true)
5828 .Case("bycopy", true)
5829 .Case("byref", true)
5830 .Default(false))
5831 Tokens[I].int_data[0] = CXToken_Keyword;
5832 continue;
5833 }
5834
5835 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5836 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5837 Tokens[I].int_data[0] = CXToken_Keyword;
5838 continue;
5839 }
5840 }
5841 }
5842}
5843
5844extern "C" {
5845
5846void clang_annotateTokens(CXTranslationUnit TU,
5847 CXToken *Tokens, unsigned NumTokens,
5848 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005849 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005850 LOG_BAD_TU(TU);
5851 return;
5852 }
5853 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005854 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005855 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005856 }
5857
5858 LOG_FUNC_SECTION {
5859 *Log << TU << ' ';
5860 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5861 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5862 *Log << clang_getRange(bloc, eloc);
5863 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005864
5865 // Any token we don't specifically annotate will have a NULL cursor.
5866 CXCursor C = clang_getNullCursor();
5867 for (unsigned I = 0; I != NumTokens; ++I)
5868 Cursors[I] = C;
5869
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005870 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005871 if (!CXXUnit)
5872 return;
5873
5874 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5875
5876 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5877 llvm::CrashRecoveryContext CRC;
5878 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5879 GetSafetyThreadStackSize() * 2)) {
5880 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5881 }
5882}
5883
5884} // end: extern "C"
5885
5886//===----------------------------------------------------------------------===//
5887// Operations for querying linkage of a cursor.
5888//===----------------------------------------------------------------------===//
5889
5890extern "C" {
5891CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5892 if (!clang_isDeclaration(cursor.kind))
5893 return CXLinkage_Invalid;
5894
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005895 const Decl *D = cxcursor::getCursorDecl(cursor);
5896 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005897 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005898 case NoLinkage:
5899 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005900 case InternalLinkage: return CXLinkage_Internal;
5901 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5902 case ExternalLinkage: return CXLinkage_External;
5903 };
5904
5905 return CXLinkage_Invalid;
5906}
5907} // end: extern "C"
5908
5909//===----------------------------------------------------------------------===//
5910// Operations for querying language of a cursor.
5911//===----------------------------------------------------------------------===//
5912
5913static CXLanguageKind getDeclLanguage(const Decl *D) {
5914 if (!D)
5915 return CXLanguage_C;
5916
5917 switch (D->getKind()) {
5918 default:
5919 break;
5920 case Decl::ImplicitParam:
5921 case Decl::ObjCAtDefsField:
5922 case Decl::ObjCCategory:
5923 case Decl::ObjCCategoryImpl:
5924 case Decl::ObjCCompatibleAlias:
5925 case Decl::ObjCImplementation:
5926 case Decl::ObjCInterface:
5927 case Decl::ObjCIvar:
5928 case Decl::ObjCMethod:
5929 case Decl::ObjCProperty:
5930 case Decl::ObjCPropertyImpl:
5931 case Decl::ObjCProtocol:
5932 return CXLanguage_ObjC;
5933 case Decl::CXXConstructor:
5934 case Decl::CXXConversion:
5935 case Decl::CXXDestructor:
5936 case Decl::CXXMethod:
5937 case Decl::CXXRecord:
5938 case Decl::ClassTemplate:
5939 case Decl::ClassTemplatePartialSpecialization:
5940 case Decl::ClassTemplateSpecialization:
5941 case Decl::Friend:
5942 case Decl::FriendTemplate:
5943 case Decl::FunctionTemplate:
5944 case Decl::LinkageSpec:
5945 case Decl::Namespace:
5946 case Decl::NamespaceAlias:
5947 case Decl::NonTypeTemplateParm:
5948 case Decl::StaticAssert:
5949 case Decl::TemplateTemplateParm:
5950 case Decl::TemplateTypeParm:
5951 case Decl::UnresolvedUsingTypename:
5952 case Decl::UnresolvedUsingValue:
5953 case Decl::Using:
5954 case Decl::UsingDirective:
5955 case Decl::UsingShadow:
5956 return CXLanguage_CPlusPlus;
5957 }
5958
5959 return CXLanguage_C;
5960}
5961
5962extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005963
5964static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5965 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5966 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005967
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005968 switch (D->getAvailability()) {
5969 case AR_Available:
5970 case AR_NotYetIntroduced:
5971 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005972 return getCursorAvailabilityForDecl(
5973 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005974 return CXAvailability_Available;
5975
5976 case AR_Deprecated:
5977 return CXAvailability_Deprecated;
5978
5979 case AR_Unavailable:
5980 return CXAvailability_NotAvailable;
5981 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005982
5983 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005984}
5985
Guy Benyei11169dd2012-12-18 14:30:41 +00005986enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5987 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005988 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5989 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005990
5991 return CXAvailability_Available;
5992}
5993
5994static CXVersion convertVersion(VersionTuple In) {
5995 CXVersion Out = { -1, -1, -1 };
5996 if (In.empty())
5997 return Out;
5998
5999 Out.Major = In.getMajor();
6000
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006001 Optional<unsigned> Minor = In.getMinor();
6002 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006003 Out.Minor = *Minor;
6004 else
6005 return Out;
6006
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006007 Optional<unsigned> Subminor = In.getSubminor();
6008 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006009 Out.Subminor = *Subminor;
6010
6011 return Out;
6012}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006013
6014static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6015 int *always_deprecated,
6016 CXString *deprecated_message,
6017 int *always_unavailable,
6018 CXString *unavailable_message,
6019 CXPlatformAvailability *availability,
6020 int availability_size) {
6021 bool HadAvailAttr = false;
6022 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006023 for (auto A : D->attrs()) {
6024 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006025 HadAvailAttr = true;
6026 if (always_deprecated)
6027 *always_deprecated = 1;
6028 if (deprecated_message)
6029 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
6030 continue;
6031 }
6032
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006033 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006034 HadAvailAttr = true;
6035 if (always_unavailable)
6036 *always_unavailable = 1;
6037 if (unavailable_message) {
6038 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6039 }
6040 continue;
6041 }
6042
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006043 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006044 HadAvailAttr = true;
6045 if (N < availability_size) {
6046 availability[N].Platform
6047 = cxstring::createDup(Avail->getPlatform()->getName());
6048 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6049 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6050 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6051 availability[N].Unavailable = Avail->getUnavailable();
6052 availability[N].Message = cxstring::createDup(Avail->getMessage());
6053 }
6054 ++N;
6055 }
6056 }
6057
6058 if (!HadAvailAttr)
6059 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6060 return getCursorPlatformAvailabilityForDecl(
6061 cast<Decl>(EnumConst->getDeclContext()),
6062 always_deprecated,
6063 deprecated_message,
6064 always_unavailable,
6065 unavailable_message,
6066 availability,
6067 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006068
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006069 return N;
6070}
6071
Guy Benyei11169dd2012-12-18 14:30:41 +00006072int clang_getCursorPlatformAvailability(CXCursor cursor,
6073 int *always_deprecated,
6074 CXString *deprecated_message,
6075 int *always_unavailable,
6076 CXString *unavailable_message,
6077 CXPlatformAvailability *availability,
6078 int availability_size) {
6079 if (always_deprecated)
6080 *always_deprecated = 0;
6081 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006082 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006083 if (always_unavailable)
6084 *always_unavailable = 0;
6085 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006086 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006087
Guy Benyei11169dd2012-12-18 14:30:41 +00006088 if (!clang_isDeclaration(cursor.kind))
6089 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006090
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006091 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006092 if (!D)
6093 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006094
6095 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6096 deprecated_message,
6097 always_unavailable,
6098 unavailable_message,
6099 availability,
6100 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006101}
6102
6103void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6104 clang_disposeString(availability->Platform);
6105 clang_disposeString(availability->Message);
6106}
6107
6108CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6109 if (clang_isDeclaration(cursor.kind))
6110 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6111
6112 return CXLanguage_Invalid;
6113}
6114
6115 /// \brief If the given cursor is the "templated" declaration
6116 /// descibing a class or function template, return the class or
6117 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006118static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006119 if (!D)
6120 return 0;
6121
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006122 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006123 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6124 return FunTmpl;
6125
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006126 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006127 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6128 return ClassTmpl;
6129
6130 return D;
6131}
6132
6133CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6134 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006135 if (const Decl *D = getCursorDecl(cursor)) {
6136 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006137 if (!DC)
6138 return clang_getNullCursor();
6139
6140 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6141 getCursorTU(cursor));
6142 }
6143 }
6144
6145 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006146 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006147 return MakeCXCursor(D, getCursorTU(cursor));
6148 }
6149
6150 return clang_getNullCursor();
6151}
6152
6153CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6154 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006155 if (const Decl *D = getCursorDecl(cursor)) {
6156 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006157 if (!DC)
6158 return clang_getNullCursor();
6159
6160 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6161 getCursorTU(cursor));
6162 }
6163 }
6164
6165 // FIXME: Note that we can't easily compute the lexical context of a
6166 // statement or expression, so we return nothing.
6167 return clang_getNullCursor();
6168}
6169
6170CXFile clang_getIncludedFile(CXCursor cursor) {
6171 if (cursor.kind != CXCursor_InclusionDirective)
6172 return 0;
6173
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006174 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006175 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006176}
6177
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006178unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6179 if (C.kind != CXCursor_ObjCPropertyDecl)
6180 return CXObjCPropertyAttr_noattr;
6181
6182 unsigned Result = CXObjCPropertyAttr_noattr;
6183 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6184 ObjCPropertyDecl::PropertyAttributeKind Attr =
6185 PD->getPropertyAttributesAsWritten();
6186
6187#define SET_CXOBJCPROP_ATTR(A) \
6188 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6189 Result |= CXObjCPropertyAttr_##A
6190 SET_CXOBJCPROP_ATTR(readonly);
6191 SET_CXOBJCPROP_ATTR(getter);
6192 SET_CXOBJCPROP_ATTR(assign);
6193 SET_CXOBJCPROP_ATTR(readwrite);
6194 SET_CXOBJCPROP_ATTR(retain);
6195 SET_CXOBJCPROP_ATTR(copy);
6196 SET_CXOBJCPROP_ATTR(nonatomic);
6197 SET_CXOBJCPROP_ATTR(setter);
6198 SET_CXOBJCPROP_ATTR(atomic);
6199 SET_CXOBJCPROP_ATTR(weak);
6200 SET_CXOBJCPROP_ATTR(strong);
6201 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6202#undef SET_CXOBJCPROP_ATTR
6203
6204 return Result;
6205}
6206
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006207unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6208 if (!clang_isDeclaration(C.kind))
6209 return CXObjCDeclQualifier_None;
6210
6211 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6212 const Decl *D = getCursorDecl(C);
6213 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6214 QT = MD->getObjCDeclQualifier();
6215 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6216 QT = PD->getObjCDeclQualifier();
6217 if (QT == Decl::OBJC_TQ_None)
6218 return CXObjCDeclQualifier_None;
6219
6220 unsigned Result = CXObjCDeclQualifier_None;
6221 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6222 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6223 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6224 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6225 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6226 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6227
6228 return Result;
6229}
6230
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006231unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6232 if (!clang_isDeclaration(C.kind))
6233 return 0;
6234
6235 const Decl *D = getCursorDecl(C);
6236 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6237 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6238 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6239 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6240
6241 return 0;
6242}
6243
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006244unsigned clang_Cursor_isVariadic(CXCursor C) {
6245 if (!clang_isDeclaration(C.kind))
6246 return 0;
6247
6248 const Decl *D = getCursorDecl(C);
6249 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6250 return FD->isVariadic();
6251 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6252 return MD->isVariadic();
6253
6254 return 0;
6255}
6256
Guy Benyei11169dd2012-12-18 14:30:41 +00006257CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6258 if (!clang_isDeclaration(C.kind))
6259 return clang_getNullRange();
6260
6261 const Decl *D = getCursorDecl(C);
6262 ASTContext &Context = getCursorContext(C);
6263 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6264 if (!RC)
6265 return clang_getNullRange();
6266
6267 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6268}
6269
6270CXString clang_Cursor_getRawCommentText(CXCursor C) {
6271 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006272 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006273
6274 const Decl *D = getCursorDecl(C);
6275 ASTContext &Context = getCursorContext(C);
6276 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6277 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6278 StringRef();
6279
6280 // Don't duplicate the string because RawText points directly into source
6281 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006282 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006283}
6284
6285CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6286 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006287 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006288
6289 const Decl *D = getCursorDecl(C);
6290 const ASTContext &Context = getCursorContext(C);
6291 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6292
6293 if (RC) {
6294 StringRef BriefText = RC->getBriefText(Context);
6295
6296 // Don't duplicate the string because RawComment ensures that this memory
6297 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006298 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006299 }
6300
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006301 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006302}
6303
6304CXComment clang_Cursor_getParsedComment(CXCursor C) {
6305 if (!clang_isDeclaration(C.kind))
6306 return cxcomment::createCXComment(NULL, NULL);
6307
6308 const Decl *D = getCursorDecl(C);
6309 const ASTContext &Context = getCursorContext(C);
6310 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6311
6312 return cxcomment::createCXComment(FC, getCursorTU(C));
6313}
6314
6315CXModule clang_Cursor_getModule(CXCursor C) {
6316 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006317 if (const ImportDecl *ImportD =
6318 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006319 return ImportD->getImportedModule();
6320 }
6321
6322 return 0;
6323}
6324
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006325CXFile clang_Module_getASTFile(CXModule CXMod) {
6326 if (!CXMod)
6327 return 0;
6328 Module *Mod = static_cast<Module*>(CXMod);
6329 return const_cast<FileEntry *>(Mod->getASTFile());
6330}
6331
Guy Benyei11169dd2012-12-18 14:30:41 +00006332CXModule clang_Module_getParent(CXModule CXMod) {
6333 if (!CXMod)
6334 return 0;
6335 Module *Mod = static_cast<Module*>(CXMod);
6336 return Mod->Parent;
6337}
6338
6339CXString clang_Module_getName(CXModule CXMod) {
6340 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006341 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006342 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006343 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006344}
6345
6346CXString clang_Module_getFullName(CXModule CXMod) {
6347 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006348 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006349 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006350 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006351}
6352
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006353unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6354 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006355 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006356 LOG_BAD_TU(TU);
6357 return 0;
6358 }
6359 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006360 return 0;
6361 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006362 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6363 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6364 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006365}
6366
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006367CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6368 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006369 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006370 LOG_BAD_TU(TU);
6371 return 0;
6372 }
6373 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006374 return 0;
6375 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006376 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006377
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006378 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6379 if (Index < TopHeaders.size())
6380 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006381
6382 return 0;
6383}
6384
6385} // end: extern "C"
6386
6387//===----------------------------------------------------------------------===//
6388// C++ AST instrospection.
6389//===----------------------------------------------------------------------===//
6390
6391extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006392unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6393 if (!clang_isDeclaration(C.kind))
6394 return 0;
6395
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006396 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006397 const CXXMethodDecl *Method =
6398 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006399 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6400}
6401
Guy Benyei11169dd2012-12-18 14:30:41 +00006402unsigned clang_CXXMethod_isStatic(CXCursor C) {
6403 if (!clang_isDeclaration(C.kind))
6404 return 0;
6405
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006406 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006407 const CXXMethodDecl *Method =
6408 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006409 return (Method && Method->isStatic()) ? 1 : 0;
6410}
6411
6412unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6413 if (!clang_isDeclaration(C.kind))
6414 return 0;
6415
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006416 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006417 const CXXMethodDecl *Method =
6418 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006419 return (Method && Method->isVirtual()) ? 1 : 0;
6420}
6421} // end: extern "C"
6422
6423//===----------------------------------------------------------------------===//
6424// Attribute introspection.
6425//===----------------------------------------------------------------------===//
6426
6427extern "C" {
6428CXType clang_getIBOutletCollectionType(CXCursor C) {
6429 if (C.kind != CXCursor_IBOutletCollectionAttr)
6430 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6431
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006432 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006433 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6434
6435 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6436}
6437} // end: extern "C"
6438
6439//===----------------------------------------------------------------------===//
6440// Inspecting memory usage.
6441//===----------------------------------------------------------------------===//
6442
6443typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6444
6445static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6446 enum CXTUResourceUsageKind k,
6447 unsigned long amount) {
6448 CXTUResourceUsageEntry entry = { k, amount };
6449 entries.push_back(entry);
6450}
6451
6452extern "C" {
6453
6454const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6455 const char *str = "";
6456 switch (kind) {
6457 case CXTUResourceUsage_AST:
6458 str = "ASTContext: expressions, declarations, and types";
6459 break;
6460 case CXTUResourceUsage_Identifiers:
6461 str = "ASTContext: identifiers";
6462 break;
6463 case CXTUResourceUsage_Selectors:
6464 str = "ASTContext: selectors";
6465 break;
6466 case CXTUResourceUsage_GlobalCompletionResults:
6467 str = "Code completion: cached global results";
6468 break;
6469 case CXTUResourceUsage_SourceManagerContentCache:
6470 str = "SourceManager: content cache allocator";
6471 break;
6472 case CXTUResourceUsage_AST_SideTables:
6473 str = "ASTContext: side tables";
6474 break;
6475 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6476 str = "SourceManager: malloc'ed memory buffers";
6477 break;
6478 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6479 str = "SourceManager: mmap'ed memory buffers";
6480 break;
6481 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6482 str = "ExternalASTSource: malloc'ed memory buffers";
6483 break;
6484 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6485 str = "ExternalASTSource: mmap'ed memory buffers";
6486 break;
6487 case CXTUResourceUsage_Preprocessor:
6488 str = "Preprocessor: malloc'ed memory";
6489 break;
6490 case CXTUResourceUsage_PreprocessingRecord:
6491 str = "Preprocessor: PreprocessingRecord";
6492 break;
6493 case CXTUResourceUsage_SourceManager_DataStructures:
6494 str = "SourceManager: data structures and tables";
6495 break;
6496 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6497 str = "Preprocessor: header search tables";
6498 break;
6499 }
6500 return str;
6501}
6502
6503CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006504 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006505 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006506 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6507 return usage;
6508 }
6509
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006510 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006511 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006512 ASTContext &astContext = astUnit->getASTContext();
6513
6514 // How much memory is used by AST nodes and types?
6515 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6516 (unsigned long) astContext.getASTAllocatedMemory());
6517
6518 // How much memory is used by identifiers?
6519 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6520 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6521
6522 // How much memory is used for selectors?
6523 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6524 (unsigned long) astContext.Selectors.getTotalMemory());
6525
6526 // How much memory is used by ASTContext's side tables?
6527 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6528 (unsigned long) astContext.getSideTableAllocatedMemory());
6529
6530 // How much memory is used for caching global code completion results?
6531 unsigned long completionBytes = 0;
6532 if (GlobalCodeCompletionAllocator *completionAllocator =
6533 astUnit->getCachedCompletionAllocator().getPtr()) {
6534 completionBytes = completionAllocator->getTotalMemory();
6535 }
6536 createCXTUResourceUsageEntry(*entries,
6537 CXTUResourceUsage_GlobalCompletionResults,
6538 completionBytes);
6539
6540 // How much memory is being used by SourceManager's content cache?
6541 createCXTUResourceUsageEntry(*entries,
6542 CXTUResourceUsage_SourceManagerContentCache,
6543 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6544
6545 // How much memory is being used by the MemoryBuffer's in SourceManager?
6546 const SourceManager::MemoryBufferSizes &srcBufs =
6547 astUnit->getSourceManager().getMemoryBufferSizes();
6548
6549 createCXTUResourceUsageEntry(*entries,
6550 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6551 (unsigned long) srcBufs.malloc_bytes);
6552 createCXTUResourceUsageEntry(*entries,
6553 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6554 (unsigned long) srcBufs.mmap_bytes);
6555 createCXTUResourceUsageEntry(*entries,
6556 CXTUResourceUsage_SourceManager_DataStructures,
6557 (unsigned long) astContext.getSourceManager()
6558 .getDataStructureSizes());
6559
6560 // How much memory is being used by the ExternalASTSource?
6561 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6562 const ExternalASTSource::MemoryBufferSizes &sizes =
6563 esrc->getMemoryBufferSizes();
6564
6565 createCXTUResourceUsageEntry(*entries,
6566 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6567 (unsigned long) sizes.malloc_bytes);
6568 createCXTUResourceUsageEntry(*entries,
6569 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6570 (unsigned long) sizes.mmap_bytes);
6571 }
6572
6573 // How much memory is being used by the Preprocessor?
6574 Preprocessor &pp = astUnit->getPreprocessor();
6575 createCXTUResourceUsageEntry(*entries,
6576 CXTUResourceUsage_Preprocessor,
6577 pp.getTotalMemory());
6578
6579 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6580 createCXTUResourceUsageEntry(*entries,
6581 CXTUResourceUsage_PreprocessingRecord,
6582 pRec->getTotalMemory());
6583 }
6584
6585 createCXTUResourceUsageEntry(*entries,
6586 CXTUResourceUsage_Preprocessor_HeaderSearch,
6587 pp.getHeaderSearchInfo().getTotalMemory());
6588
6589 CXTUResourceUsage usage = { (void*) entries.get(),
6590 (unsigned) entries->size(),
6591 entries->size() ? &(*entries)[0] : 0 };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006592 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006593 return usage;
6594}
6595
6596void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6597 if (usage.data)
6598 delete (MemUsageEntries*) usage.data;
6599}
6600
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006601CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6602 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006603 skipped->count = 0;
6604 skipped->ranges = 0;
6605
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006606 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006607 LOG_BAD_TU(TU);
6608 return skipped;
6609 }
6610
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006611 if (!file)
6612 return skipped;
6613
6614 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6615 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6616 if (!ppRec)
6617 return skipped;
6618
6619 ASTContext &Ctx = astUnit->getASTContext();
6620 SourceManager &sm = Ctx.getSourceManager();
6621 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6622 FileID wantedFileID = sm.translateFile(fileEntry);
6623
6624 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6625 std::vector<SourceRange> wantedRanges;
6626 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6627 i != ei; ++i) {
6628 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6629 wantedRanges.push_back(*i);
6630 }
6631
6632 skipped->count = wantedRanges.size();
6633 skipped->ranges = new CXSourceRange[skipped->count];
6634 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6635 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6636
6637 return skipped;
6638}
6639
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006640void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6641 if (ranges) {
6642 delete[] ranges->ranges;
6643 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006644 }
6645}
6646
Guy Benyei11169dd2012-12-18 14:30:41 +00006647} // end extern "C"
6648
6649void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6650 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6651 for (unsigned I = 0; I != Usage.numEntries; ++I)
6652 fprintf(stderr, " %s: %lu\n",
6653 clang_getTUResourceUsageName(Usage.entries[I].kind),
6654 Usage.entries[I].amount);
6655
6656 clang_disposeCXTUResourceUsage(Usage);
6657}
6658
6659//===----------------------------------------------------------------------===//
6660// Misc. utility functions.
6661//===----------------------------------------------------------------------===//
6662
6663/// Default to using an 8 MB stack size on "safety" threads.
6664static unsigned SafetyStackThreadSize = 8 << 20;
6665
6666namespace clang {
6667
6668bool RunSafely(llvm::CrashRecoveryContext &CRC,
6669 void (*Fn)(void*), void *UserData,
6670 unsigned Size) {
6671 if (!Size)
6672 Size = GetSafetyThreadStackSize();
6673 if (Size)
6674 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6675 return CRC.RunSafely(Fn, UserData);
6676}
6677
6678unsigned GetSafetyThreadStackSize() {
6679 return SafetyStackThreadSize;
6680}
6681
6682void SetSafetyThreadStackSize(unsigned Value) {
6683 SafetyStackThreadSize = Value;
6684}
6685
6686}
6687
6688void clang::setThreadBackgroundPriority() {
6689 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6690 return;
6691
6692 // FIXME: Move to llvm/Support and make it cross-platform.
6693#ifdef __APPLE__
6694 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6695#endif
6696}
6697
6698void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6699 if (!Unit)
6700 return;
6701
6702 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6703 DEnd = Unit->stored_diag_end();
6704 D != DEnd; ++D) {
6705 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6706 CXString Msg = clang_formatDiagnostic(&Diag,
6707 clang_defaultDiagnosticDisplayOptions());
6708 fprintf(stderr, "%s\n", clang_getCString(Msg));
6709 clang_disposeString(Msg);
6710 }
6711#ifdef LLVM_ON_WIN32
6712 // On Windows, force a flush, since there may be multiple copies of
6713 // stderr and stdout in the file system, all with different buffers
6714 // but writing to the same device.
6715 fflush(stderr);
6716#endif
6717}
6718
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006719MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6720 SourceLocation MacroDefLoc,
6721 CXTranslationUnit TU){
6722 if (MacroDefLoc.isInvalid() || !TU)
6723 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006724 if (!II.hadMacroDefinition())
6725 return 0;
6726
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006727 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006728 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006729 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006730 if (MD) {
6731 for (MacroDirective::DefInfo
6732 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6733 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6734 return Def.getMacroInfo();
6735 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006736 }
6737
6738 return 0;
6739}
6740
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006741const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6742 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006743 if (!MacroDef || !TU)
6744 return 0;
6745 const IdentifierInfo *II = MacroDef->getName();
6746 if (!II)
6747 return 0;
6748
6749 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6750}
6751
6752MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6753 const Token &Tok,
6754 CXTranslationUnit TU) {
6755 if (!MI || !TU)
6756 return 0;
6757 if (Tok.isNot(tok::raw_identifier))
6758 return 0;
6759
6760 if (MI->getNumTokens() == 0)
6761 return 0;
6762 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6763 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006764 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006765
6766 // Check that the token is inside the definition and not its argument list.
6767 SourceManager &SM = Unit->getSourceManager();
6768 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6769 return 0;
6770 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6771 return 0;
6772
6773 Preprocessor &PP = Unit->getPreprocessor();
6774 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6775 if (!PPRec)
6776 return 0;
6777
6778 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6779 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6780 if (!II.hadMacroDefinition())
6781 return 0;
6782
6783 // Check that the identifier is not one of the macro arguments.
6784 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6785 return 0;
6786
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006787 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6788 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006789 return 0;
6790
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006791 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006792}
6793
6794MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6795 SourceLocation Loc,
6796 CXTranslationUnit TU) {
6797 if (Loc.isInvalid() || !MI || !TU)
6798 return 0;
6799
6800 if (MI->getNumTokens() == 0)
6801 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006802 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006803 Preprocessor &PP = Unit->getPreprocessor();
6804 if (!PP.getPreprocessingRecord())
6805 return 0;
6806 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6807 Token Tok;
6808 if (PP.getRawToken(Loc, Tok))
6809 return 0;
6810
6811 return checkForMacroInMacroDefinition(MI, Tok, TU);
6812}
6813
Guy Benyei11169dd2012-12-18 14:30:41 +00006814extern "C" {
6815
6816CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006817 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006818}
6819
6820} // end: extern "C"
6821
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006822Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6823 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006824 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006825 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006826 if (Unit->isMainFileAST())
6827 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006828 return *this;
6829 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006830 } else {
6831 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006832 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006833 return *this;
6834}
6835
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006836Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6837 *this << FE->getName();
6838 return *this;
6839}
6840
6841Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6842 CXString cursorName = clang_getCursorDisplayName(cursor);
6843 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6844 clang_disposeString(cursorName);
6845 return *this;
6846}
6847
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006848Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6849 CXFile File;
6850 unsigned Line, Column;
6851 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6852 CXString FileName = clang_getFileName(File);
6853 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6854 clang_disposeString(FileName);
6855 return *this;
6856}
6857
6858Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6859 CXSourceLocation BLoc = clang_getRangeStart(range);
6860 CXSourceLocation ELoc = clang_getRangeEnd(range);
6861
6862 CXFile BFile;
6863 unsigned BLine, BColumn;
6864 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6865
6866 CXFile EFile;
6867 unsigned ELine, EColumn;
6868 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6869
6870 CXString BFileName = clang_getFileName(BFile);
6871 if (BFile == EFile) {
6872 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6873 BLine, BColumn, ELine, EColumn);
6874 } else {
6875 CXString EFileName = clang_getFileName(EFile);
6876 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6877 BLine, BColumn)
6878 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6879 ELine, EColumn);
6880 clang_disposeString(EFileName);
6881 }
6882 clang_disposeString(BFileName);
6883 return *this;
6884}
6885
6886Logger &cxindex::Logger::operator<<(CXString Str) {
6887 *this << clang_getCString(Str);
6888 return *this;
6889}
6890
6891Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6892 LogOS << Fmt;
6893 return *this;
6894}
6895
6896cxindex::Logger::~Logger() {
6897 LogOS.flush();
6898
6899 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6900
6901 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6902
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006903 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006904 OS << "[libclang:" << Name << ':';
6905
6906 // FIXME: Portability.
6907#if HAVE_PTHREAD_H && __APPLE__
6908 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6909 OS << tid << ':';
6910#endif
6911
6912 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6913 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6914 OS << Msg.str() << '\n';
6915
6916 if (Trace) {
6917 llvm::sys::PrintStackTrace(stderr);
6918 OS << "--------------------------------------------------\n";
6919 }
6920}