blob: 456bdcc553697754b5ce8933c9763957c74ae6e9 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXComment.h"
19#include "CXCursor.h"
20#include "CXSourceLocation.h"
21#include "CXString.h"
22#include "CXTranslationUnit.h"
23#include "CXType.h"
24#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000025#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000030#include "clang/Basic/Version.h"
31#include "clang/Frontend/ASTUnit.h"
32#include "clang/Frontend/CompilerInstance.h"
33#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000034#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000035#include "clang/Lex/HeaderSearch.h"
36#include "clang/Lex/Lexer.h"
37#include "clang/Lex/PreprocessingRecord.h"
38#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000039#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000040#include "llvm/ADT/Optional.h"
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/StringSwitch.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000043#include "llvm/Config/config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000044#include "llvm/Support/Compiler.h"
45#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000046#include "llvm/Support/Format.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/MemoryBuffer.h"
48#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000049#include "llvm/Support/Program.h"
50#include "llvm/Support/SaveAndRestore.h"
51#include "llvm/Support/Signals.h"
52#include "llvm/Support/Threading.h"
53#include "llvm/Support/Timer.h"
54#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000055
56#if HAVE_PTHREAD_H
57#include <pthread.h>
58#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000059
60using namespace clang;
61using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000062using namespace clang::cxtu;
63using namespace clang::cxindex;
64
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000065CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
66 if (!AU)
Guy Benyei11169dd2012-12-18 14:30:41 +000067 return 0;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000068 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000069 CXTranslationUnit D = new CXTranslationUnitImpl();
70 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000071 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000072 D->StringPool = new cxstring::CXStringPool();
Guy Benyei11169dd2012-12-18 14:30:41 +000073 D->Diagnostics = 0;
74 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Dmitri Gribenko9e605112013-11-13 22:16:51 +000075 D->CommentToXML = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +000076 return D;
77}
78
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000079bool cxtu::isASTReadError(ASTUnit *AU) {
80 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
81 DEnd = AU->stored_diag_end();
82 D != DEnd; ++D) {
83 if (D->getLevel() >= DiagnosticsEngine::Error &&
84 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
85 diag::DiagCat_AST_Deserialization_Issue)
86 return true;
87 }
88 return false;
89}
90
Guy Benyei11169dd2012-12-18 14:30:41 +000091cxtu::CXTUOwner::~CXTUOwner() {
92 if (TU)
93 clang_disposeTranslationUnit(TU);
94}
95
96/// \brief Compare two source ranges to determine their relative position in
97/// the translation unit.
98static RangeComparisonResult RangeCompare(SourceManager &SM,
99 SourceRange R1,
100 SourceRange R2) {
101 assert(R1.isValid() && "First range is invalid?");
102 assert(R2.isValid() && "Second range is invalid?");
103 if (R1.getEnd() != R2.getBegin() &&
104 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
105 return RangeBefore;
106 if (R2.getEnd() != R1.getBegin() &&
107 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
108 return RangeAfter;
109 return RangeOverlap;
110}
111
112/// \brief Determine if a source location falls within, before, or after a
113/// a given source range.
114static RangeComparisonResult LocationCompare(SourceManager &SM,
115 SourceLocation L, SourceRange R) {
116 assert(R.isValid() && "First range is invalid?");
117 assert(L.isValid() && "Second range is invalid?");
118 if (L == R.getBegin() || L == R.getEnd())
119 return RangeOverlap;
120 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
121 return RangeBefore;
122 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
123 return RangeAfter;
124 return RangeOverlap;
125}
126
127/// \brief Translate a Clang source range into a CIndex source range.
128///
129/// Clang internally represents ranges where the end location points to the
130/// start of the token at the end. However, for external clients it is more
131/// useful to have a CXSourceRange be a proper half-open interval. This routine
132/// does the appropriate translation.
133CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
134 const LangOptions &LangOpts,
135 const CharSourceRange &R) {
136 // We want the last character in this location, so we will adjust the
137 // location accordingly.
138 SourceLocation EndLoc = R.getEnd();
139 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
140 EndLoc = SM.getExpansionRange(EndLoc).second;
141 if (R.isTokenRange() && !EndLoc.isInvalid()) {
142 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
143 SM, LangOpts);
144 EndLoc = EndLoc.getLocWithOffset(Length);
145 }
146
Bill Wendlingeade3622013-01-23 08:25:41 +0000147 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000148 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000149 R.getBegin().getRawEncoding(),
150 EndLoc.getRawEncoding()
151 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000152 return Result;
153}
154
155//===----------------------------------------------------------------------===//
156// Cursor visitor.
157//===----------------------------------------------------------------------===//
158
159static SourceRange getRawCursorExtent(CXCursor C);
160static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
161
162
163RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
164 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
165}
166
167/// \brief Visit the given cursor and, if requested by the visitor,
168/// its children.
169///
170/// \param Cursor the cursor to visit.
171///
172/// \param CheckedRegionOfInterest if true, then the caller already checked
173/// that this cursor is within the region of interest.
174///
175/// \returns true if the visitation should be aborted, false if it
176/// should continue.
177bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
178 if (clang_isInvalid(Cursor.kind))
179 return false;
180
181 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000182 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000183 if (!D) {
184 assert(0 && "Invalid declaration cursor");
185 return true; // abort.
186 }
187
188 // Ignore implicit declarations, unless it's an objc method because
189 // currently we should report implicit methods for properties when indexing.
190 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
191 return false;
192 }
193
194 // If we have a range of interest, and this cursor doesn't intersect with it,
195 // we're done.
196 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
197 SourceRange Range = getRawCursorExtent(Cursor);
198 if (Range.isInvalid() || CompareRegionOfInterest(Range))
199 return false;
200 }
201
202 switch (Visitor(Cursor, Parent, ClientData)) {
203 case CXChildVisit_Break:
204 return true;
205
206 case CXChildVisit_Continue:
207 return false;
208
209 case CXChildVisit_Recurse: {
210 bool ret = VisitChildren(Cursor);
211 if (PostChildrenVisitor)
212 if (PostChildrenVisitor(Cursor, ClientData))
213 return true;
214 return ret;
215 }
216 }
217
218 llvm_unreachable("Invalid CXChildVisitResult!");
219}
220
221static bool visitPreprocessedEntitiesInRange(SourceRange R,
222 PreprocessingRecord &PPRec,
223 CursorVisitor &Visitor) {
224 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
225 FileID FID;
226
227 if (!Visitor.shouldVisitIncludedEntities()) {
228 // If the begin/end of the range lie in the same FileID, do the optimization
229 // where we skip preprocessed entities that do not come from the same FileID.
230 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
231 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
232 FID = FileID();
233 }
234
235 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
236 Entities = PPRec.getPreprocessedEntitiesInRange(R);
237 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
238 PPRec, FID);
239}
240
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000241bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000242 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000243 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000244
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000245 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 SourceManager &SM = Unit->getSourceManager();
247
248 std::pair<FileID, unsigned>
249 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
250 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
251
252 if (End.first != Begin.first) {
253 // If the end does not reside in the same file, try to recover by
254 // picking the end of the file of begin location.
255 End.first = Begin.first;
256 End.second = SM.getFileIDSize(Begin.first);
257 }
258
259 assert(Begin.first == End.first);
260 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000261 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000262
263 FileID File = Begin.first;
264 unsigned Offset = Begin.second;
265 unsigned Length = End.second - Begin.second;
266
267 if (!VisitDeclsOnly && !VisitPreprocessorLast)
268 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000271 if (visitDeclsFromFileRegion(File, Offset, Length))
272 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000273
274 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000275 return visitPreprocessedEntitiesInRegion();
276
277 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000278}
279
280static bool isInLexicalContext(Decl *D, DeclContext *DC) {
281 if (!DC)
282 return false;
283
284 for (DeclContext *DeclDC = D->getLexicalDeclContext();
285 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
286 if (DeclDC == DC)
287 return true;
288 }
289 return false;
290}
291
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000292bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000293 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000294 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000295 SourceManager &SM = Unit->getSourceManager();
296 SourceRange Range = RegionOfInterest;
297
298 SmallVector<Decl *, 16> Decls;
299 Unit->findFileRegionDecls(File, Offset, Length, Decls);
300
301 // If we didn't find any file level decls for the file, try looking at the
302 // file that it was included from.
303 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
304 bool Invalid = false;
305 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
306 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000307 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000308
309 SourceLocation Outer;
310 if (SLEntry.isFile())
311 Outer = SLEntry.getFile().getIncludeLoc();
312 else
313 Outer = SLEntry.getExpansion().getExpansionLocStart();
314 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000317 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000318 Length = 0;
319 Unit->findFileRegionDecls(File, Offset, Length, Decls);
320 }
321
322 assert(!Decls.empty());
323
324 bool VisitedAtLeastOnce = false;
325 DeclContext *CurDC = 0;
Craig Topper2341c0d2013-07-04 03:08:24 +0000326 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
327 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000328 Decl *D = *DIt;
329 if (D->getSourceRange().isInvalid())
330 continue;
331
332 if (isInLexicalContext(D, CurDC))
333 continue;
334
335 CurDC = dyn_cast<DeclContext>(D);
336
337 if (TagDecl *TD = dyn_cast<TagDecl>(D))
338 if (!TD->isFreeStanding())
339 continue;
340
341 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
342 if (CompRes == RangeBefore)
343 continue;
344 if (CompRes == RangeAfter)
345 break;
346
347 assert(CompRes == RangeOverlap);
348 VisitedAtLeastOnce = true;
349
350 if (isa<ObjCContainerDecl>(D)) {
351 FileDI_current = &DIt;
352 FileDE_current = DE;
353 } else {
354 FileDI_current = 0;
355 }
356
357 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000358 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000359 }
360
361 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000362 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363
364 // No Decls overlapped with the range. Move up the lexical context until there
365 // is a context that contains the range or we reach the translation unit
366 // level.
367 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
368 : (*(DIt-1))->getLexicalDeclContext();
369
370 while (DC && !DC->isTranslationUnit()) {
371 Decl *D = cast<Decl>(DC);
372 SourceRange CurDeclRange = D->getSourceRange();
373 if (CurDeclRange.isInvalid())
374 break;
375
376 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000377 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
378 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000379 }
380
381 DC = D->getLexicalDeclContext();
382 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000383
384 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000385}
386
387bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
388 if (!AU->getPreprocessor().getPreprocessingRecord())
389 return false;
390
391 PreprocessingRecord &PPRec
392 = *AU->getPreprocessor().getPreprocessingRecord();
393 SourceManager &SM = AU->getSourceManager();
394
395 if (RegionOfInterest.isValid()) {
396 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
397 SourceLocation B = MappedRange.getBegin();
398 SourceLocation E = MappedRange.getEnd();
399
400 if (AU->isInPreambleFileID(B)) {
401 if (SM.isLoadedSourceLocation(E))
402 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
403 PPRec, *this);
404
405 // Beginning of range lies in the preamble but it also extends beyond
406 // it into the main file. Split the range into 2 parts, one covering
407 // the preamble and another covering the main file. This allows subsequent
408 // calls to visitPreprocessedEntitiesInRange to accept a source range that
409 // lies in the same FileID, allowing it to skip preprocessed entities that
410 // do not come from the same FileID.
411 bool breaked =
412 visitPreprocessedEntitiesInRange(
413 SourceRange(B, AU->getEndOfPreambleFileID()),
414 PPRec, *this);
415 if (breaked) return true;
416 return visitPreprocessedEntitiesInRange(
417 SourceRange(AU->getStartOfMainFileID(), E),
418 PPRec, *this);
419 }
420
421 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
422 }
423
424 bool OnlyLocalDecls
425 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
426
427 if (OnlyLocalDecls)
428 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
429 PPRec);
430
431 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
432}
433
434template<typename InputIterator>
435bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
436 InputIterator Last,
437 PreprocessingRecord &PPRec,
438 FileID FID) {
439 for (; First != Last; ++First) {
440 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
441 continue;
442
443 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000444 if (!PPE)
445 continue;
446
Guy Benyei11169dd2012-12-18 14:30:41 +0000447 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
448 if (Visit(MakeMacroExpansionCursor(ME, TU)))
449 return true;
450
451 continue;
452 }
453
454 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
455 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
456 return true;
457
458 continue;
459 }
460
461 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
462 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
463 return true;
464
465 continue;
466 }
467 }
468
469 return false;
470}
471
472/// \brief Visit the children of the given cursor.
473///
474/// \returns true if the visitation should be aborted, false if it
475/// should continue.
476bool CursorVisitor::VisitChildren(CXCursor Cursor) {
477 if (clang_isReference(Cursor.kind) &&
478 Cursor.kind != CXCursor_CXXBaseSpecifier) {
479 // By definition, references have no children.
480 return false;
481 }
482
483 // Set the Parent field to Cursor, then back to its old value once we're
484 // done.
485 SetParentRAII SetParent(Parent, StmtParent, Cursor);
486
487 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000488 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000489 if (!D)
490 return false;
491
492 return VisitAttributes(D) || Visit(D);
493 }
494
495 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000496 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 return Visit(S);
498
499 return false;
500 }
501
502 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000503 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000504 return Visit(E);
505
506 return false;
507 }
508
509 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000510 CXTranslationUnit TU = getCursorTU(Cursor);
511 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000512
513 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
514 for (unsigned I = 0; I != 2; ++I) {
515 if (VisitOrder[I]) {
516 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
517 RegionOfInterest.isInvalid()) {
518 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
519 TLEnd = CXXUnit->top_level_end();
520 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000521 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000522 return true;
523 }
524 } else if (VisitDeclContext(
525 CXXUnit->getASTContext().getTranslationUnitDecl()))
526 return true;
527 continue;
528 }
529
530 // Walk the preprocessing record.
531 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
532 visitPreprocessedEntitiesInRegion();
533 }
534
535 return false;
536 }
537
538 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000539 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000540 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
541 return Visit(BaseTSInfo->getTypeLoc());
542 }
543 }
544 }
545
546 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000547 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000549 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000550 return Visit(cxcursor::MakeCursorObjCClassRef(
551 ObjT->getInterface(),
552 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000553 }
554
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000555 // If pointing inside a macro definition, check if the token is an identifier
556 // that was ever defined as a macro. In such a case, create a "pseudo" macro
557 // expansion cursor for that token.
558 SourceLocation BeginLoc = RegionOfInterest.getBegin();
559 if (Cursor.kind == CXCursor_MacroDefinition &&
560 BeginLoc == RegionOfInterest.getEnd()) {
561 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000562 const MacroInfo *MI =
563 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000564 if (MacroDefinition *MacroDef =
565 checkForMacroInMacroDefinition(MI, Loc, TU))
566 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
567 }
568
Guy Benyei11169dd2012-12-18 14:30:41 +0000569 // Nothing to visit at the moment.
570 return false;
571}
572
573bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
574 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
575 if (Visit(TSInfo->getTypeLoc()))
576 return true;
577
578 if (Stmt *Body = B->getBody())
579 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
580
581 return false;
582}
583
Ted Kremenek03325582013-02-21 01:29:01 +0000584Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000585 if (RegionOfInterest.isValid()) {
586 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
587 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000588 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000589
590 switch (CompareRegionOfInterest(Range)) {
591 case RangeBefore:
592 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000593 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000594
595 case RangeAfter:
596 // This declaration comes after the region of interest; we're done.
597 return false;
598
599 case RangeOverlap:
600 // This declaration overlaps the region of interest; visit it.
601 break;
602 }
603 }
604 return true;
605}
606
607bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
608 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
609
610 // FIXME: Eventually remove. This part of a hack to support proper
611 // iteration over all Decls contained lexically within an ObjC container.
612 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
613 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
614
615 for ( ; I != E; ++I) {
616 Decl *D = *I;
617 if (D->getLexicalDeclContext() != DC)
618 continue;
619 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
620
621 // Ignore synthesized ivars here, otherwise if we have something like:
622 // @synthesize prop = _prop;
623 // and '_prop' is not declared, we will encounter a '_prop' ivar before
624 // encountering the 'prop' synthesize declaration and we will think that
625 // we passed the region-of-interest.
626 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
627 if (ivarD->getSynthesize())
628 continue;
629 }
630
631 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
632 // declarations is a mismatch with the compiler semantics.
633 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
634 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
635 if (!ID->isThisDeclarationADefinition())
636 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
637
638 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
639 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
640 if (!PD->isThisDeclarationADefinition())
641 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
642 }
643
Ted Kremenek03325582013-02-21 01:29:01 +0000644 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000645 if (!V.hasValue())
646 continue;
647 if (!V.getValue())
648 return false;
649 if (Visit(Cursor, true))
650 return true;
651 }
652 return false;
653}
654
655bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
656 llvm_unreachable("Translation units are visited directly by Visit()");
657}
658
659bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
660 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
661 return Visit(TSInfo->getTypeLoc());
662
663 return false;
664}
665
666bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
667 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
668 return Visit(TSInfo->getTypeLoc());
669
670 return false;
671}
672
673bool CursorVisitor::VisitTagDecl(TagDecl *D) {
674 return VisitDeclContext(D);
675}
676
677bool CursorVisitor::VisitClassTemplateSpecializationDecl(
678 ClassTemplateSpecializationDecl *D) {
679 bool ShouldVisitBody = false;
680 switch (D->getSpecializationKind()) {
681 case TSK_Undeclared:
682 case TSK_ImplicitInstantiation:
683 // Nothing to visit
684 return false;
685
686 case TSK_ExplicitInstantiationDeclaration:
687 case TSK_ExplicitInstantiationDefinition:
688 break;
689
690 case TSK_ExplicitSpecialization:
691 ShouldVisitBody = true;
692 break;
693 }
694
695 // Visit the template arguments used in the specialization.
696 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
697 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000698 if (TemplateSpecializationTypeLoc TSTLoc =
699 TL.getAs<TemplateSpecializationTypeLoc>()) {
700 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
701 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000702 return true;
703 }
704 }
705
706 if (ShouldVisitBody && VisitCXXRecordDecl(D))
707 return true;
708
709 return false;
710}
711
712bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
713 ClassTemplatePartialSpecializationDecl *D) {
714 // FIXME: Visit the "outer" template parameter lists on the TagDecl
715 // before visiting these template parameters.
716 if (VisitTemplateParameters(D->getTemplateParameters()))
717 return true;
718
719 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000720 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
721 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
722 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000723 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
724 return true;
725
726 return VisitCXXRecordDecl(D);
727}
728
729bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
730 // Visit the default argument.
731 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
732 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
733 if (Visit(DefArg->getTypeLoc()))
734 return true;
735
736 return false;
737}
738
739bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
740 if (Expr *Init = D->getInitExpr())
741 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
742 return false;
743}
744
745bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000746 unsigned NumParamList = DD->getNumTemplateParameterLists();
747 for (unsigned i = 0; i < NumParamList; i++) {
748 TemplateParameterList* Params = DD->getTemplateParameterList(i);
749 if (VisitTemplateParameters(Params))
750 return true;
751 }
752
Guy Benyei11169dd2012-12-18 14:30:41 +0000753 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
754 if (Visit(TSInfo->getTypeLoc()))
755 return true;
756
757 // Visit the nested-name-specifier, if present.
758 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
759 if (VisitNestedNameSpecifierLoc(QualifierLoc))
760 return true;
761
762 return false;
763}
764
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000765/// \brief Compare two base or member initializers based on their source order.
766static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
767 CXXCtorInitializer *const *Y) {
768 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
769}
770
Guy Benyei11169dd2012-12-18 14:30:41 +0000771bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000772 unsigned NumParamList = ND->getNumTemplateParameterLists();
773 for (unsigned i = 0; i < NumParamList; i++) {
774 TemplateParameterList* Params = ND->getTemplateParameterList(i);
775 if (VisitTemplateParameters(Params))
776 return true;
777 }
778
Guy Benyei11169dd2012-12-18 14:30:41 +0000779 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
780 // Visit the function declaration's syntactic components in the order
781 // written. This requires a bit of work.
782 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000783 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000784
785 // If we have a function declared directly (without the use of a typedef),
786 // visit just the return type. Otherwise, just visit the function's type
787 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000788 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000789 (!FTL && Visit(TL)))
790 return true;
791
792 // Visit the nested-name-specifier, if present.
793 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
794 if (VisitNestedNameSpecifierLoc(QualifierLoc))
795 return true;
796
797 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000798 if (!isa<CXXDestructorDecl>(ND))
799 if (VisitDeclarationNameInfo(ND->getNameInfo()))
800 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000801
802 // FIXME: Visit explicitly-specified template arguments!
803
804 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000805 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000806 return true;
807
Bill Wendling44426052012-12-20 19:22:21 +0000808 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000809 }
810
811 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
812 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
813 // Find the initializers that were written in the source.
814 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
815 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
816 IEnd = Constructor->init_end();
817 I != IEnd; ++I) {
818 if (!(*I)->isWritten())
819 continue;
820
821 WrittenInits.push_back(*I);
822 }
823
824 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000825 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
826 &CompareCXXCtorInitializers);
827
Guy Benyei11169dd2012-12-18 14:30:41 +0000828 // Visit the initializers in source order
829 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
830 CXXCtorInitializer *Init = WrittenInits[I];
831 if (Init->isAnyMemberInitializer()) {
832 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
833 Init->getMemberLocation(), TU)))
834 return true;
835 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
836 if (Visit(TInfo->getTypeLoc()))
837 return true;
838 }
839
840 // Visit the initializer value.
841 if (Expr *Initializer = Init->getInit())
842 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
843 return true;
844 }
845 }
846
847 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
848 return true;
849 }
850
851 return false;
852}
853
854bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
855 if (VisitDeclaratorDecl(D))
856 return true;
857
858 if (Expr *BitWidth = D->getBitWidth())
859 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
860
861 return false;
862}
863
864bool CursorVisitor::VisitVarDecl(VarDecl *D) {
865 if (VisitDeclaratorDecl(D))
866 return true;
867
868 if (Expr *Init = D->getInit())
869 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
870
871 return false;
872}
873
874bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
875 if (VisitDeclaratorDecl(D))
876 return true;
877
878 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
879 if (Expr *DefArg = D->getDefaultArgument())
880 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
881
882 return false;
883}
884
885bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
886 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
887 // before visiting these template parameters.
888 if (VisitTemplateParameters(D->getTemplateParameters()))
889 return true;
890
891 return VisitFunctionDecl(D->getTemplatedDecl());
892}
893
894bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
895 // FIXME: Visit the "outer" template parameter lists on the TagDecl
896 // before visiting these template parameters.
897 if (VisitTemplateParameters(D->getTemplateParameters()))
898 return true;
899
900 return VisitCXXRecordDecl(D->getTemplatedDecl());
901}
902
903bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
904 if (VisitTemplateParameters(D->getTemplateParameters()))
905 return true;
906
907 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
908 VisitTemplateArgumentLoc(D->getDefaultArgument()))
909 return true;
910
911 return false;
912}
913
914bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000915 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000916 if (Visit(TSInfo->getTypeLoc()))
917 return true;
918
Aaron Ballman43b68be2014-03-07 17:50:17 +0000919 for (const auto *P : ND->params()) {
920 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000921 return true;
922 }
923
924 if (ND->isThisDeclarationADefinition() &&
925 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
926 return true;
927
928 return false;
929}
930
931template <typename DeclIt>
932static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
933 SourceManager &SM, SourceLocation EndLoc,
934 SmallVectorImpl<Decl *> &Decls) {
935 DeclIt next = *DI_current;
936 while (++next != DE_current) {
937 Decl *D_next = *next;
938 if (!D_next)
939 break;
940 SourceLocation L = D_next->getLocStart();
941 if (!L.isValid())
942 break;
943 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
944 *DI_current = next;
945 Decls.push_back(D_next);
946 continue;
947 }
948 break;
949 }
950}
951
Guy Benyei11169dd2012-12-18 14:30:41 +0000952bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
953 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
954 // an @implementation can lexically contain Decls that are not properly
955 // nested in the AST. When we identify such cases, we need to retrofit
956 // this nesting here.
957 if (!DI_current && !FileDI_current)
958 return VisitDeclContext(D);
959
960 // Scan the Decls that immediately come after the container
961 // in the current DeclContext. If any fall within the
962 // container's lexical region, stash them into a vector
963 // for later processing.
964 SmallVector<Decl *, 24> DeclsInContainer;
965 SourceLocation EndLoc = D->getSourceRange().getEnd();
966 SourceManager &SM = AU->getSourceManager();
967 if (EndLoc.isValid()) {
968 if (DI_current) {
969 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
970 DeclsInContainer);
971 } else {
972 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
973 DeclsInContainer);
974 }
975 }
976
977 // The common case.
978 if (DeclsInContainer.empty())
979 return VisitDeclContext(D);
980
981 // Get all the Decls in the DeclContext, and sort them with the
982 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000983 for (auto *SubDecl : D->decls()) {
984 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
985 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000986 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000987 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000988 }
989
990 // Now sort the Decls so that they appear in lexical order.
991 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000992 [&SM](Decl *A, Decl *B) {
993 SourceLocation L_A = A->getLocStart();
994 SourceLocation L_B = B->getLocStart();
995 assert(L_A.isValid() && L_B.isValid());
996 return SM.isBeforeInTranslationUnit(L_A, L_B);
997 });
Guy Benyei11169dd2012-12-18 14:30:41 +0000998
999 // Now visit the decls.
1000 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1001 E = DeclsInContainer.end(); I != E; ++I) {
1002 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001003 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001004 if (!V.hasValue())
1005 continue;
1006 if (!V.getValue())
1007 return false;
1008 if (Visit(Cursor, true))
1009 return true;
1010 }
1011 return false;
1012}
1013
1014bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1015 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1016 TU)))
1017 return true;
1018
1019 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1020 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1021 E = ND->protocol_end(); I != E; ++I, ++PL)
1022 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1023 return true;
1024
1025 return VisitObjCContainerDecl(ND);
1026}
1027
1028bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1029 if (!PID->isThisDeclarationADefinition())
1030 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1031
1032 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1033 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1034 E = PID->protocol_end(); I != E; ++I, ++PL)
1035 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1036 return true;
1037
1038 return VisitObjCContainerDecl(PID);
1039}
1040
1041bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1042 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1043 return true;
1044
1045 // FIXME: This implements a workaround with @property declarations also being
1046 // installed in the DeclContext for the @interface. Eventually this code
1047 // should be removed.
1048 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1049 if (!CDecl || !CDecl->IsClassExtension())
1050 return false;
1051
1052 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1053 if (!ID)
1054 return false;
1055
1056 IdentifierInfo *PropertyId = PD->getIdentifier();
1057 ObjCPropertyDecl *prevDecl =
1058 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1059
1060 if (!prevDecl)
1061 return false;
1062
1063 // Visit synthesized methods since they will be skipped when visiting
1064 // the @interface.
1065 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1066 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1067 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1068 return true;
1069
1070 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1071 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1072 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1073 return true;
1074
1075 return false;
1076}
1077
1078bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1079 if (!D->isThisDeclarationADefinition()) {
1080 // Forward declaration is treated like a reference.
1081 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1082 }
1083
1084 // Issue callbacks for super class.
1085 if (D->getSuperClass() &&
1086 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1087 D->getSuperClassLoc(),
1088 TU)))
1089 return true;
1090
1091 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1092 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1093 E = D->protocol_end(); I != E; ++I, ++PL)
1094 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1095 return true;
1096
1097 return VisitObjCContainerDecl(D);
1098}
1099
1100bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1101 return VisitObjCContainerDecl(D);
1102}
1103
1104bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1105 // 'ID' could be null when dealing with invalid code.
1106 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1107 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1108 return true;
1109
1110 return VisitObjCImplDecl(D);
1111}
1112
1113bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1114#if 0
1115 // Issue callbacks for super class.
1116 // FIXME: No source location information!
1117 if (D->getSuperClass() &&
1118 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1119 D->getSuperClassLoc(),
1120 TU)))
1121 return true;
1122#endif
1123
1124 return VisitObjCImplDecl(D);
1125}
1126
1127bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1128 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1129 if (PD->isIvarNameSpecified())
1130 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1131
1132 return false;
1133}
1134
1135bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1136 return VisitDeclContext(D);
1137}
1138
1139bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1140 // Visit nested-name-specifier.
1141 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1142 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1143 return true;
1144
1145 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1146 D->getTargetNameLoc(), TU));
1147}
1148
1149bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1150 // Visit nested-name-specifier.
1151 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1152 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1153 return true;
1154 }
1155
1156 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1157 return true;
1158
1159 return VisitDeclarationNameInfo(D->getNameInfo());
1160}
1161
1162bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1163 // Visit nested-name-specifier.
1164 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1165 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1166 return true;
1167
1168 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1169 D->getIdentLocation(), TU));
1170}
1171
1172bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1173 // Visit nested-name-specifier.
1174 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1175 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1176 return true;
1177 }
1178
1179 return VisitDeclarationNameInfo(D->getNameInfo());
1180}
1181
1182bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1183 UnresolvedUsingTypenameDecl *D) {
1184 // Visit nested-name-specifier.
1185 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1186 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1187 return true;
1188
1189 return false;
1190}
1191
1192bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1193 switch (Name.getName().getNameKind()) {
1194 case clang::DeclarationName::Identifier:
1195 case clang::DeclarationName::CXXLiteralOperatorName:
1196 case clang::DeclarationName::CXXOperatorName:
1197 case clang::DeclarationName::CXXUsingDirective:
1198 return false;
1199
1200 case clang::DeclarationName::CXXConstructorName:
1201 case clang::DeclarationName::CXXDestructorName:
1202 case clang::DeclarationName::CXXConversionFunctionName:
1203 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1204 return Visit(TSInfo->getTypeLoc());
1205 return false;
1206
1207 case clang::DeclarationName::ObjCZeroArgSelector:
1208 case clang::DeclarationName::ObjCOneArgSelector:
1209 case clang::DeclarationName::ObjCMultiArgSelector:
1210 // FIXME: Per-identifier location info?
1211 return false;
1212 }
1213
1214 llvm_unreachable("Invalid DeclarationName::Kind!");
1215}
1216
1217bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1218 SourceRange Range) {
1219 // FIXME: This whole routine is a hack to work around the lack of proper
1220 // source information in nested-name-specifiers (PR5791). Since we do have
1221 // a beginning source location, we can visit the first component of the
1222 // nested-name-specifier, if it's a single-token component.
1223 if (!NNS)
1224 return false;
1225
1226 // Get the first component in the nested-name-specifier.
1227 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1228 NNS = Prefix;
1229
1230 switch (NNS->getKind()) {
1231 case NestedNameSpecifier::Namespace:
1232 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1233 TU));
1234
1235 case NestedNameSpecifier::NamespaceAlias:
1236 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1237 Range.getBegin(), TU));
1238
1239 case NestedNameSpecifier::TypeSpec: {
1240 // If the type has a form where we know that the beginning of the source
1241 // range matches up with a reference cursor. Visit the appropriate reference
1242 // cursor.
1243 const Type *T = NNS->getAsType();
1244 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1245 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1246 if (const TagType *Tag = dyn_cast<TagType>(T))
1247 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1248 if (const TemplateSpecializationType *TST
1249 = dyn_cast<TemplateSpecializationType>(T))
1250 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1251 break;
1252 }
1253
1254 case NestedNameSpecifier::TypeSpecWithTemplate:
1255 case NestedNameSpecifier::Global:
1256 case NestedNameSpecifier::Identifier:
1257 break;
1258 }
1259
1260 return false;
1261}
1262
1263bool
1264CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1265 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1266 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1267 Qualifiers.push_back(Qualifier);
1268
1269 while (!Qualifiers.empty()) {
1270 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1271 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1272 switch (NNS->getKind()) {
1273 case NestedNameSpecifier::Namespace:
1274 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1275 Q.getLocalBeginLoc(),
1276 TU)))
1277 return true;
1278
1279 break;
1280
1281 case NestedNameSpecifier::NamespaceAlias:
1282 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1283 Q.getLocalBeginLoc(),
1284 TU)))
1285 return true;
1286
1287 break;
1288
1289 case NestedNameSpecifier::TypeSpec:
1290 case NestedNameSpecifier::TypeSpecWithTemplate:
1291 if (Visit(Q.getTypeLoc()))
1292 return true;
1293
1294 break;
1295
1296 case NestedNameSpecifier::Global:
1297 case NestedNameSpecifier::Identifier:
1298 break;
1299 }
1300 }
1301
1302 return false;
1303}
1304
1305bool CursorVisitor::VisitTemplateParameters(
1306 const TemplateParameterList *Params) {
1307 if (!Params)
1308 return false;
1309
1310 for (TemplateParameterList::const_iterator P = Params->begin(),
1311 PEnd = Params->end();
1312 P != PEnd; ++P) {
1313 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1314 return true;
1315 }
1316
1317 return false;
1318}
1319
1320bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1321 switch (Name.getKind()) {
1322 case TemplateName::Template:
1323 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1324
1325 case TemplateName::OverloadedTemplate:
1326 // Visit the overloaded template set.
1327 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1328 return true;
1329
1330 return false;
1331
1332 case TemplateName::DependentTemplate:
1333 // FIXME: Visit nested-name-specifier.
1334 return false;
1335
1336 case TemplateName::QualifiedTemplate:
1337 // FIXME: Visit nested-name-specifier.
1338 return Visit(MakeCursorTemplateRef(
1339 Name.getAsQualifiedTemplateName()->getDecl(),
1340 Loc, TU));
1341
1342 case TemplateName::SubstTemplateTemplateParm:
1343 return Visit(MakeCursorTemplateRef(
1344 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1345 Loc, TU));
1346
1347 case TemplateName::SubstTemplateTemplateParmPack:
1348 return Visit(MakeCursorTemplateRef(
1349 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1350 Loc, TU));
1351 }
1352
1353 llvm_unreachable("Invalid TemplateName::Kind!");
1354}
1355
1356bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1357 switch (TAL.getArgument().getKind()) {
1358 case TemplateArgument::Null:
1359 case TemplateArgument::Integral:
1360 case TemplateArgument::Pack:
1361 return false;
1362
1363 case TemplateArgument::Type:
1364 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1365 return Visit(TSInfo->getTypeLoc());
1366 return false;
1367
1368 case TemplateArgument::Declaration:
1369 if (Expr *E = TAL.getSourceDeclExpression())
1370 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1371 return false;
1372
1373 case TemplateArgument::NullPtr:
1374 if (Expr *E = TAL.getSourceNullPtrExpression())
1375 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1376 return false;
1377
1378 case TemplateArgument::Expression:
1379 if (Expr *E = TAL.getSourceExpression())
1380 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1381 return false;
1382
1383 case TemplateArgument::Template:
1384 case TemplateArgument::TemplateExpansion:
1385 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1386 return true;
1387
1388 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1389 TAL.getTemplateNameLoc());
1390 }
1391
1392 llvm_unreachable("Invalid TemplateArgument::Kind!");
1393}
1394
1395bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1396 return VisitDeclContext(D);
1397}
1398
1399bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1400 return Visit(TL.getUnqualifiedLoc());
1401}
1402
1403bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1404 ASTContext &Context = AU->getASTContext();
1405
1406 // Some builtin types (such as Objective-C's "id", "sel", and
1407 // "Class") have associated declarations. Create cursors for those.
1408 QualType VisitType;
1409 switch (TL.getTypePtr()->getKind()) {
1410
1411 case BuiltinType::Void:
1412 case BuiltinType::NullPtr:
1413 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001414 case BuiltinType::OCLImage1d:
1415 case BuiltinType::OCLImage1dArray:
1416 case BuiltinType::OCLImage1dBuffer:
1417 case BuiltinType::OCLImage2d:
1418 case BuiltinType::OCLImage2dArray:
1419 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001420 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001421 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001422#define BUILTIN_TYPE(Id, SingletonId)
1423#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1424#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1425#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1426#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1427#include "clang/AST/BuiltinTypes.def"
1428 break;
1429
1430 case BuiltinType::ObjCId:
1431 VisitType = Context.getObjCIdType();
1432 break;
1433
1434 case BuiltinType::ObjCClass:
1435 VisitType = Context.getObjCClassType();
1436 break;
1437
1438 case BuiltinType::ObjCSel:
1439 VisitType = Context.getObjCSelType();
1440 break;
1441 }
1442
1443 if (!VisitType.isNull()) {
1444 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1445 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1446 TU));
1447 }
1448
1449 return false;
1450}
1451
1452bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1453 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1454}
1455
1456bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1457 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1458}
1459
1460bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1461 if (TL.isDefinition())
1462 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1463
1464 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1465}
1466
1467bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1468 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1469}
1470
1471bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1472 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1473 return true;
1474
1475 return false;
1476}
1477
1478bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1479 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1480 return true;
1481
1482 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1483 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1484 TU)))
1485 return true;
1486 }
1487
1488 return false;
1489}
1490
1491bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1492 return Visit(TL.getPointeeLoc());
1493}
1494
1495bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1496 return Visit(TL.getInnerLoc());
1497}
1498
1499bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1500 return Visit(TL.getPointeeLoc());
1501}
1502
1503bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1504 return Visit(TL.getPointeeLoc());
1505}
1506
1507bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1508 return Visit(TL.getPointeeLoc());
1509}
1510
1511bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1512 return Visit(TL.getPointeeLoc());
1513}
1514
1515bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1516 return Visit(TL.getPointeeLoc());
1517}
1518
1519bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1520 return Visit(TL.getModifiedLoc());
1521}
1522
1523bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1524 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001525 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001526 return true;
1527
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001528 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1529 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001530 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1531 return true;
1532
1533 return false;
1534}
1535
1536bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1537 if (Visit(TL.getElementLoc()))
1538 return true;
1539
1540 if (Expr *Size = TL.getSizeExpr())
1541 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1542
1543 return false;
1544}
1545
Reid Kleckner8a365022013-06-24 17:51:48 +00001546bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1547 return Visit(TL.getOriginalLoc());
1548}
1549
Reid Kleckner0503a872013-12-05 01:23:43 +00001550bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1551 return Visit(TL.getOriginalLoc());
1552}
1553
Guy Benyei11169dd2012-12-18 14:30:41 +00001554bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1555 TemplateSpecializationTypeLoc TL) {
1556 // Visit the template name.
1557 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1558 TL.getTemplateNameLoc()))
1559 return true;
1560
1561 // Visit the template arguments.
1562 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1563 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1564 return true;
1565
1566 return false;
1567}
1568
1569bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1570 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1571}
1572
1573bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1574 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1575 return Visit(TSInfo->getTypeLoc());
1576
1577 return false;
1578}
1579
1580bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1581 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1582 return Visit(TSInfo->getTypeLoc());
1583
1584 return false;
1585}
1586
1587bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1588 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1589 return true;
1590
1591 return false;
1592}
1593
1594bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1595 DependentTemplateSpecializationTypeLoc TL) {
1596 // Visit the nested-name-specifier, if there is one.
1597 if (TL.getQualifierLoc() &&
1598 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1599 return true;
1600
1601 // Visit the template arguments.
1602 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1603 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1604 return true;
1605
1606 return false;
1607}
1608
1609bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1610 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1611 return true;
1612
1613 return Visit(TL.getNamedTypeLoc());
1614}
1615
1616bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1617 return Visit(TL.getPatternLoc());
1618}
1619
1620bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1621 if (Expr *E = TL.getUnderlyingExpr())
1622 return Visit(MakeCXCursor(E, StmtParent, TU));
1623
1624 return false;
1625}
1626
1627bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1628 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1629}
1630
1631bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1632 return Visit(TL.getValueLoc());
1633}
1634
1635#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1636bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1637 return Visit##PARENT##Loc(TL); \
1638}
1639
1640DEFAULT_TYPELOC_IMPL(Complex, Type)
1641DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1642DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1643DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1644DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1645DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1646DEFAULT_TYPELOC_IMPL(Vector, Type)
1647DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1648DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1649DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1650DEFAULT_TYPELOC_IMPL(Record, TagType)
1651DEFAULT_TYPELOC_IMPL(Enum, TagType)
1652DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1653DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1654DEFAULT_TYPELOC_IMPL(Auto, Type)
1655
1656bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1657 // Visit the nested-name-specifier, if present.
1658 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1659 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1660 return true;
1661
1662 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001663 for (const auto &I : D->bases()) {
1664 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001665 return true;
1666 }
1667 }
1668
1669 return VisitTagDecl(D);
1670}
1671
1672bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001673 for (const auto *I : D->attrs())
1674 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001675 return true;
1676
1677 return false;
1678}
1679
1680//===----------------------------------------------------------------------===//
1681// Data-recursive visitor methods.
1682//===----------------------------------------------------------------------===//
1683
1684namespace {
1685#define DEF_JOB(NAME, DATA, KIND)\
1686class NAME : public VisitorJob {\
1687public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001688 NAME(const DATA *d, CXCursor parent) : \
1689 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001690 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001691 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001692};
1693
1694DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1695DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1696DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1697DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1698DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1699 ExplicitTemplateArgsVisitKind)
1700DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1701DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1702DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1703#undef DEF_JOB
1704
1705class DeclVisit : public VisitorJob {
1706public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001707 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001708 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001709 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001710 static bool classof(const VisitorJob *VJ) {
1711 return VJ->getKind() == DeclVisitKind;
1712 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001713 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001714 bool isFirst() const { return data[1] ? true : false; }
1715};
1716class TypeLocVisit : public VisitorJob {
1717public:
1718 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1719 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1720 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1721
1722 static bool classof(const VisitorJob *VJ) {
1723 return VJ->getKind() == TypeLocVisitKind;
1724 }
1725
1726 TypeLoc get() const {
1727 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001728 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001729 }
1730};
1731
1732class LabelRefVisit : public VisitorJob {
1733public:
1734 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1735 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1736 labelLoc.getPtrEncoding()) {}
1737
1738 static bool classof(const VisitorJob *VJ) {
1739 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1740 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001741 const LabelDecl *get() const {
1742 return static_cast<const LabelDecl *>(data[0]);
1743 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001744 SourceLocation getLoc() const {
1745 return SourceLocation::getFromPtrEncoding(data[1]); }
1746};
1747
1748class NestedNameSpecifierLocVisit : public VisitorJob {
1749public:
1750 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1751 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1752 Qualifier.getNestedNameSpecifier(),
1753 Qualifier.getOpaqueData()) { }
1754
1755 static bool classof(const VisitorJob *VJ) {
1756 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1757 }
1758
1759 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001760 return NestedNameSpecifierLoc(
1761 const_cast<NestedNameSpecifier *>(
1762 static_cast<const NestedNameSpecifier *>(data[0])),
1763 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001764 }
1765};
1766
1767class DeclarationNameInfoVisit : public VisitorJob {
1768public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001769 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001770 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001771 static bool classof(const VisitorJob *VJ) {
1772 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1773 }
1774 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001775 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001776 switch (S->getStmtClass()) {
1777 default:
1778 llvm_unreachable("Unhandled Stmt");
1779 case clang::Stmt::MSDependentExistsStmtClass:
1780 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1781 case Stmt::CXXDependentScopeMemberExprClass:
1782 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1783 case Stmt::DependentScopeDeclRefExprClass:
1784 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1785 }
1786 }
1787};
1788class MemberRefVisit : public VisitorJob {
1789public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001790 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001791 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1792 L.getPtrEncoding()) {}
1793 static bool classof(const VisitorJob *VJ) {
1794 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1795 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001796 const FieldDecl *get() const {
1797 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001798 }
1799 SourceLocation getLoc() const {
1800 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1801 }
1802};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001803class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001804 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001805 VisitorWorkList &WL;
1806 CXCursor Parent;
1807public:
1808 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1809 : WL(wl), Parent(parent) {}
1810
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001811 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1812 void VisitBlockExpr(const BlockExpr *B);
1813 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1814 void VisitCompoundStmt(const CompoundStmt *S);
1815 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1816 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1817 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1818 void VisitCXXNewExpr(const CXXNewExpr *E);
1819 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1820 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1821 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1822 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1823 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1824 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1825 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1826 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1827 void VisitDeclRefExpr(const DeclRefExpr *D);
1828 void VisitDeclStmt(const DeclStmt *S);
1829 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1830 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1831 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1832 void VisitForStmt(const ForStmt *FS);
1833 void VisitGotoStmt(const GotoStmt *GS);
1834 void VisitIfStmt(const IfStmt *If);
1835 void VisitInitListExpr(const InitListExpr *IE);
1836 void VisitMemberExpr(const MemberExpr *M);
1837 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1838 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1839 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1840 void VisitOverloadExpr(const OverloadExpr *E);
1841 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1842 void VisitStmt(const Stmt *S);
1843 void VisitSwitchStmt(const SwitchStmt *S);
1844 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001845 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1846 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1847 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1848 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1849 void VisitVAArgExpr(const VAArgExpr *E);
1850 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1851 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1852 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1853 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001854 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1855 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001856 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001857
Guy Benyei11169dd2012-12-18 14:30:41 +00001858private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001859 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001860 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1861 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001862 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1863 void AddStmt(const Stmt *S);
1864 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001865 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001866 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001867 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001868};
1869} // end anonyous namespace
1870
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001871void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001872 // 'S' should always be non-null, since it comes from the
1873 // statement we are visiting.
1874 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1875}
1876
1877void
1878EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1879 if (Qualifier)
1880 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1881}
1882
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001883void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001884 if (S)
1885 WL.push_back(StmtVisit(S, Parent));
1886}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001887void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001888 if (D)
1889 WL.push_back(DeclVisit(D, Parent, isFirst));
1890}
1891void EnqueueVisitor::
1892 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1893 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001894 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001895}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001896void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001897 if (D)
1898 WL.push_back(MemberRefVisit(D, L, Parent));
1899}
1900void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1901 if (TI)
1902 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1903 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001904void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001905 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001906 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001907 AddStmt(*Child);
1908 }
1909 if (size == WL.size())
1910 return;
1911 // Now reverse the entries we just added. This will match the DFS
1912 // ordering performed by the worklist.
1913 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1914 std::reverse(I, E);
1915}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001916namespace {
1917class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1918 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001919 /// \brief Process clauses with list of variables.
1920 template <typename T>
1921 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001922public:
1923 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1924#define OPENMP_CLAUSE(Name, Class) \
1925 void Visit##Class(const Class *C);
1926#include "clang/Basic/OpenMPKinds.def"
1927};
1928
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001929void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1930 Visitor->AddStmt(C->getCondition());
1931}
1932
Alexey Bataev568a8332014-03-06 06:15:19 +00001933void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1934 Visitor->AddStmt(C->getNumThreads());
1935}
1936
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001937void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001938
1939template<typename T>
1940void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
1941 for (typename T::varlist_const_iterator I = Node->varlist_begin(),
1942 E = Node->varlist_end();
1943 I != E; ++I)
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001944 Visitor->AddStmt(*I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001945}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001946
1947void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001948 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001949}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001950void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1951 const OMPFirstprivateClause *C) {
1952 VisitOMPClauseList(C);
1953}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001954void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001955 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001956}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001957}
Alexey Bataev756c1962013-09-24 03:17:45 +00001958
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001959void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1960 unsigned size = WL.size();
1961 OMPClauseEnqueue Visitor(this);
1962 Visitor.Visit(S);
1963 if (size == WL.size())
1964 return;
1965 // Now reverse the entries we just added. This will match the DFS
1966 // ordering performed by the worklist.
1967 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1968 std::reverse(I, E);
1969}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001970void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001971 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1972}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001973void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001974 AddDecl(B->getBlockDecl());
1975}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001976void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001977 EnqueueChildren(E);
1978 AddTypeLoc(E->getTypeSourceInfo());
1979}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001980void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1981 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001982 E = S->body_rend(); I != E; ++I) {
1983 AddStmt(*I);
1984 }
1985}
1986void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001987VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001988 AddStmt(S->getSubStmt());
1989 AddDeclarationNameInfo(S);
1990 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1991 AddNestedNameSpecifierLoc(QualifierLoc);
1992}
1993
1994void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001995VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001996 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1997 AddDeclarationNameInfo(E);
1998 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
1999 AddNestedNameSpecifierLoc(QualifierLoc);
2000 if (!E->isImplicitAccess())
2001 AddStmt(E->getBase());
2002}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002003void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002004 // Enqueue the initializer , if any.
2005 AddStmt(E->getInitializer());
2006 // Enqueue the array size, if any.
2007 AddStmt(E->getArraySize());
2008 // Enqueue the allocated type.
2009 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2010 // Enqueue the placement arguments.
2011 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2012 AddStmt(E->getPlacementArg(I-1));
2013}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002014void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002015 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2016 AddStmt(CE->getArg(I-1));
2017 AddStmt(CE->getCallee());
2018 AddStmt(CE->getArg(0));
2019}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002020void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2021 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002022 // Visit the name of the type being destroyed.
2023 AddTypeLoc(E->getDestroyedTypeInfo());
2024 // Visit the scope type that looks disturbingly like the nested-name-specifier
2025 // but isn't.
2026 AddTypeLoc(E->getScopeTypeInfo());
2027 // Visit the nested-name-specifier.
2028 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2029 AddNestedNameSpecifierLoc(QualifierLoc);
2030 // Visit base expression.
2031 AddStmt(E->getBase());
2032}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002033void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2034 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002035 AddTypeLoc(E->getTypeSourceInfo());
2036}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002037void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2038 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002039 EnqueueChildren(E);
2040 AddTypeLoc(E->getTypeSourceInfo());
2041}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002042void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002043 EnqueueChildren(E);
2044 if (E->isTypeOperand())
2045 AddTypeLoc(E->getTypeOperandSourceInfo());
2046}
2047
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002048void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2049 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002050 EnqueueChildren(E);
2051 AddTypeLoc(E->getTypeSourceInfo());
2052}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002053void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002054 EnqueueChildren(E);
2055 if (E->isTypeOperand())
2056 AddTypeLoc(E->getTypeOperandSourceInfo());
2057}
2058
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002059void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002060 EnqueueChildren(S);
2061 AddDecl(S->getExceptionDecl());
2062}
2063
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002064void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002065 if (DR->hasExplicitTemplateArgs()) {
2066 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2067 }
2068 WL.push_back(DeclRefExprParts(DR, Parent));
2069}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002070void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2071 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002072 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2073 AddDeclarationNameInfo(E);
2074 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2075}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002076void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002077 unsigned size = WL.size();
2078 bool isFirst = true;
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002079 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00002080 D != DEnd; ++D) {
2081 AddDecl(*D, isFirst);
2082 isFirst = false;
2083 }
2084 if (size == WL.size())
2085 return;
2086 // Now reverse the entries we just added. This will match the DFS
2087 // ordering performed by the worklist.
2088 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2089 std::reverse(I, E);
2090}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002091void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002092 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002093 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002094 D = E->designators_rbegin(), DEnd = E->designators_rend();
2095 D != DEnd; ++D) {
2096 if (D->isFieldDesignator()) {
2097 if (FieldDecl *Field = D->getField())
2098 AddMemberRef(Field, D->getFieldLoc());
2099 continue;
2100 }
2101 if (D->isArrayDesignator()) {
2102 AddStmt(E->getArrayIndex(*D));
2103 continue;
2104 }
2105 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2106 AddStmt(E->getArrayRangeEnd(*D));
2107 AddStmt(E->getArrayRangeStart(*D));
2108 }
2109}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002110void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002111 EnqueueChildren(E);
2112 AddTypeLoc(E->getTypeInfoAsWritten());
2113}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002114void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002115 AddStmt(FS->getBody());
2116 AddStmt(FS->getInc());
2117 AddStmt(FS->getCond());
2118 AddDecl(FS->getConditionVariable());
2119 AddStmt(FS->getInit());
2120}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002121void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002122 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2123}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002124void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002125 AddStmt(If->getElse());
2126 AddStmt(If->getThen());
2127 AddStmt(If->getCond());
2128 AddDecl(If->getConditionVariable());
2129}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002130void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002131 // We care about the syntactic form of the initializer list, only.
2132 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2133 IE = Syntactic;
2134 EnqueueChildren(IE);
2135}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002136void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002137 WL.push_back(MemberExprParts(M, Parent));
2138
2139 // If the base of the member access expression is an implicit 'this', don't
2140 // visit it.
2141 // FIXME: If we ever want to show these implicit accesses, this will be
2142 // unfortunate. However, clang_getCursor() relies on this behavior.
2143 if (!M->isImplicitAccess())
2144 AddStmt(M->getBase());
2145}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002146void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002147 AddTypeLoc(E->getEncodedTypeSourceInfo());
2148}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002149void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002150 EnqueueChildren(M);
2151 AddTypeLoc(M->getClassReceiverTypeInfo());
2152}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002153void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002154 // Visit the components of the offsetof expression.
2155 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2156 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2157 const OffsetOfNode &Node = E->getComponent(I-1);
2158 switch (Node.getKind()) {
2159 case OffsetOfNode::Array:
2160 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2161 break;
2162 case OffsetOfNode::Field:
2163 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2164 break;
2165 case OffsetOfNode::Identifier:
2166 case OffsetOfNode::Base:
2167 continue;
2168 }
2169 }
2170 // Visit the type into which we're computing the offset.
2171 AddTypeLoc(E->getTypeSourceInfo());
2172}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002173void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002174 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2175 WL.push_back(OverloadExprParts(E, Parent));
2176}
2177void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002178 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002179 EnqueueChildren(E);
2180 if (E->isArgumentType())
2181 AddTypeLoc(E->getArgumentTypeInfo());
2182}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002183void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002184 EnqueueChildren(S);
2185}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002186void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002187 AddStmt(S->getBody());
2188 AddStmt(S->getCond());
2189 AddDecl(S->getConditionVariable());
2190}
2191
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002192void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002193 AddStmt(W->getBody());
2194 AddStmt(W->getCond());
2195 AddDecl(W->getConditionVariable());
2196}
2197
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002198void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002199 for (unsigned I = E->getNumArgs(); I > 0; --I)
2200 AddTypeLoc(E->getArg(I-1));
2201}
2202
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002203void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002204 AddTypeLoc(E->getQueriedTypeSourceInfo());
2205}
2206
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002207void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002208 EnqueueChildren(E);
2209}
2210
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002211void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002212 VisitOverloadExpr(U);
2213 if (!U->isImplicitAccess())
2214 AddStmt(U->getBase());
2215}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002216void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002217 AddStmt(E->getSubExpr());
2218 AddTypeLoc(E->getWrittenTypeInfo());
2219}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002220void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002221 WL.push_back(SizeOfPackExprParts(E, Parent));
2222}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002223void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002224 // If the opaque value has a source expression, just transparently
2225 // visit that. This is useful for (e.g.) pseudo-object expressions.
2226 if (Expr *SourceExpr = E->getSourceExpr())
2227 return Visit(SourceExpr);
2228}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002229void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002230 AddStmt(E->getBody());
2231 WL.push_back(LambdaExprParts(E, Parent));
2232}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002233void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002234 // Treat the expression like its syntactic form.
2235 Visit(E->getSyntacticForm());
2236}
2237
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002238void EnqueueVisitor::VisitOMPExecutableDirective(
2239 const OMPExecutableDirective *D) {
2240 EnqueueChildren(D);
2241 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2242 E = D->clauses().end();
2243 I != E; ++I)
2244 EnqueueChildren(*I);
2245}
2246
2247void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2248 VisitOMPExecutableDirective(D);
2249}
2250
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002251void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2252 VisitOMPExecutableDirective(D);
2253}
2254
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002255void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002256 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2257}
2258
2259bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2260 if (RegionOfInterest.isValid()) {
2261 SourceRange Range = getRawCursorExtent(C);
2262 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2263 return false;
2264 }
2265 return true;
2266}
2267
2268bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2269 while (!WL.empty()) {
2270 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002271 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002272
2273 // Set the Parent field, then back to its old value once we're done.
2274 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2275
2276 switch (LI.getKind()) {
2277 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002278 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002279 if (!D)
2280 continue;
2281
2282 // For now, perform default visitation for Decls.
2283 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2284 cast<DeclVisit>(&LI)->isFirst())))
2285 return true;
2286
2287 continue;
2288 }
2289 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2290 const ASTTemplateArgumentListInfo *ArgList =
2291 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2292 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2293 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2294 Arg != ArgEnd; ++Arg) {
2295 if (VisitTemplateArgumentLoc(*Arg))
2296 return true;
2297 }
2298 continue;
2299 }
2300 case VisitorJob::TypeLocVisitKind: {
2301 // Perform default visitation for TypeLocs.
2302 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2303 return true;
2304 continue;
2305 }
2306 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002307 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002308 if (LabelStmt *stmt = LS->getStmt()) {
2309 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2310 TU))) {
2311 return true;
2312 }
2313 }
2314 continue;
2315 }
2316
2317 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2318 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2319 if (VisitNestedNameSpecifierLoc(V->get()))
2320 return true;
2321 continue;
2322 }
2323
2324 case VisitorJob::DeclarationNameInfoVisitKind: {
2325 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2326 ->get()))
2327 return true;
2328 continue;
2329 }
2330 case VisitorJob::MemberRefVisitKind: {
2331 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2332 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2333 return true;
2334 continue;
2335 }
2336 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002337 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002338 if (!S)
2339 continue;
2340
2341 // Update the current cursor.
2342 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2343 if (!IsInRegionOfInterest(Cursor))
2344 continue;
2345 switch (Visitor(Cursor, Parent, ClientData)) {
2346 case CXChildVisit_Break: return true;
2347 case CXChildVisit_Continue: break;
2348 case CXChildVisit_Recurse:
2349 if (PostChildrenVisitor)
2350 WL.push_back(PostChildrenVisit(0, Cursor));
2351 EnqueueWorkList(WL, S);
2352 break;
2353 }
2354 continue;
2355 }
2356 case VisitorJob::MemberExprPartsKind: {
2357 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002358 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002359
2360 // Visit the nested-name-specifier
2361 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2362 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2363 return true;
2364
2365 // Visit the declaration name.
2366 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2367 return true;
2368
2369 // Visit the explicitly-specified template arguments, if any.
2370 if (M->hasExplicitTemplateArgs()) {
2371 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2372 *ArgEnd = Arg + M->getNumTemplateArgs();
2373 Arg != ArgEnd; ++Arg) {
2374 if (VisitTemplateArgumentLoc(*Arg))
2375 return true;
2376 }
2377 }
2378 continue;
2379 }
2380 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002381 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002382 // Visit nested-name-specifier, if present.
2383 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2384 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2385 return true;
2386 // Visit declaration name.
2387 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2388 return true;
2389 continue;
2390 }
2391 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002392 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002393 // Visit the nested-name-specifier.
2394 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2395 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2396 return true;
2397 // Visit the declaration name.
2398 if (VisitDeclarationNameInfo(O->getNameInfo()))
2399 return true;
2400 // Visit the overloaded declaration reference.
2401 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2402 return true;
2403 continue;
2404 }
2405 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002406 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002407 NamedDecl *Pack = E->getPack();
2408 if (isa<TemplateTypeParmDecl>(Pack)) {
2409 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2410 E->getPackLoc(), TU)))
2411 return true;
2412
2413 continue;
2414 }
2415
2416 if (isa<TemplateTemplateParmDecl>(Pack)) {
2417 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2418 E->getPackLoc(), TU)))
2419 return true;
2420
2421 continue;
2422 }
2423
2424 // Non-type template parameter packs and function parameter packs are
2425 // treated like DeclRefExpr cursors.
2426 continue;
2427 }
2428
2429 case VisitorJob::LambdaExprPartsKind: {
2430 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002431 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002432 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2433 CEnd = E->explicit_capture_end();
2434 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002435 // FIXME: Lambda init-captures.
2436 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002437 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002438
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2440 C->getLocation(),
2441 TU)))
2442 return true;
2443 }
2444
2445 // Visit parameters and return type, if present.
2446 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2447 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2448 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2449 // Visit the whole type.
2450 if (Visit(TL))
2451 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002452 } else if (FunctionProtoTypeLoc Proto =
2453 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002454 if (E->hasExplicitParameters()) {
2455 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002456 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2457 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002458 return true;
2459 } else {
2460 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002461 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002462 return true;
2463 }
2464 }
2465 }
2466 break;
2467 }
2468
2469 case VisitorJob::PostChildrenVisitKind:
2470 if (PostChildrenVisitor(Parent, ClientData))
2471 return true;
2472 break;
2473 }
2474 }
2475 return false;
2476}
2477
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002478bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002479 VisitorWorkList *WL = 0;
2480 if (!WorkListFreeList.empty()) {
2481 WL = WorkListFreeList.back();
2482 WL->clear();
2483 WorkListFreeList.pop_back();
2484 }
2485 else {
2486 WL = new VisitorWorkList();
2487 WorkListCache.push_back(WL);
2488 }
2489 EnqueueWorkList(*WL, S);
2490 bool result = RunVisitorWorkList(*WL);
2491 WorkListFreeList.push_back(WL);
2492 return result;
2493}
2494
2495namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002496typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002497RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2498 const DeclarationNameInfo &NI,
2499 const SourceRange &QLoc,
2500 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2501 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2502 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2503 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2504
2505 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2506
2507 RefNamePieces Pieces;
2508
2509 if (WantQualifier && QLoc.isValid())
2510 Pieces.push_back(QLoc);
2511
2512 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2513 Pieces.push_back(NI.getLoc());
2514
2515 if (WantTemplateArgs && TemplateArgs)
2516 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2517 TemplateArgs->RAngleLoc));
2518
2519 if (Kind == DeclarationName::CXXOperatorName) {
2520 Pieces.push_back(SourceLocation::getFromRawEncoding(
2521 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2522 Pieces.push_back(SourceLocation::getFromRawEncoding(
2523 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2524 }
2525
2526 if (WantSinglePiece) {
2527 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2528 Pieces.clear();
2529 Pieces.push_back(R);
2530 }
2531
2532 return Pieces;
2533}
2534}
2535
2536//===----------------------------------------------------------------------===//
2537// Misc. API hooks.
2538//===----------------------------------------------------------------------===//
2539
2540static llvm::sys::Mutex EnableMultithreadingMutex;
2541static bool EnabledMultithreading;
2542
Chad Rosier05c71aa2013-03-27 18:28:23 +00002543static void fatal_error_handler(void *user_data, const std::string& reason,
2544 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002545 // Write the result out to stderr avoiding errs() because raw_ostreams can
2546 // call report_fatal_error.
2547 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2548 ::abort();
2549}
2550
2551extern "C" {
2552CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2553 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002554 // We use crash recovery to make some of our APIs more reliable, implicitly
2555 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002556 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2557 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002558
2559 // Enable support for multithreading in LLVM.
2560 {
2561 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2562 if (!EnabledMultithreading) {
2563 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2564 llvm::llvm_start_multithreaded();
2565 EnabledMultithreading = true;
2566 }
2567 }
2568
2569 CIndexer *CIdxr = new CIndexer();
2570 if (excludeDeclarationsFromPCH)
2571 CIdxr->setOnlyLocalDecls();
2572 if (displayDiagnostics)
2573 CIdxr->setDisplayDiagnostics();
2574
2575 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2576 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2577 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2578 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2579 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2580 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2581
2582 return CIdxr;
2583}
2584
2585void clang_disposeIndex(CXIndex CIdx) {
2586 if (CIdx)
2587 delete static_cast<CIndexer *>(CIdx);
2588}
2589
2590void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2591 if (CIdx)
2592 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2593}
2594
2595unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2596 if (CIdx)
2597 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2598 return 0;
2599}
2600
2601void clang_toggleCrashRecovery(unsigned isEnabled) {
2602 if (isEnabled)
2603 llvm::CrashRecoveryContext::Enable();
2604 else
2605 llvm::CrashRecoveryContext::Disable();
2606}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002607
Guy Benyei11169dd2012-12-18 14:30:41 +00002608CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2609 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002610 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002611 enum CXErrorCode Result =
2612 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002613 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002614 assert((TU && Result == CXError_Success) ||
2615 (!TU && Result != CXError_Success));
2616 return TU;
2617}
2618
2619enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2620 const char *ast_filename,
2621 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002622 if (out_TU)
2623 *out_TU = NULL;
2624
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002625 if (!CIdx || !ast_filename || !out_TU)
2626 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002627
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002628 LOG_FUNC_SECTION {
2629 *Log << ast_filename;
2630 }
2631
Guy Benyei11169dd2012-12-18 14:30:41 +00002632 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2633 FileSystemOptions FileSystemOpts;
2634
2635 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002636 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002637 CXXIdx->getOnlyLocalDecls(), None,
2638 /*CaptureDiagnostics=*/true,
2639 /*AllowPCHWithCompilerErrors=*/true,
2640 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002641 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2642 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002643}
2644
2645unsigned clang_defaultEditingTranslationUnitOptions() {
2646 return CXTranslationUnit_PrecompiledPreamble |
2647 CXTranslationUnit_CacheCompletionResults;
2648}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002649
Guy Benyei11169dd2012-12-18 14:30:41 +00002650CXTranslationUnit
2651clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2652 const char *source_filename,
2653 int num_command_line_args,
2654 const char * const *command_line_args,
2655 unsigned num_unsaved_files,
2656 struct CXUnsavedFile *unsaved_files) {
2657 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2658 return clang_parseTranslationUnit(CIdx, source_filename,
2659 command_line_args, num_command_line_args,
2660 unsaved_files, num_unsaved_files,
2661 Options);
2662}
2663
2664struct ParseTranslationUnitInfo {
2665 CXIndex CIdx;
2666 const char *source_filename;
2667 const char *const *command_line_args;
2668 int num_command_line_args;
2669 struct CXUnsavedFile *unsaved_files;
2670 unsigned num_unsaved_files;
2671 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002672 CXTranslationUnit *out_TU;
2673 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002674};
2675static void clang_parseTranslationUnit_Impl(void *UserData) {
2676 ParseTranslationUnitInfo *PTUI =
2677 static_cast<ParseTranslationUnitInfo*>(UserData);
2678 CXIndex CIdx = PTUI->CIdx;
2679 const char *source_filename = PTUI->source_filename;
2680 const char * const *command_line_args = PTUI->command_line_args;
2681 int num_command_line_args = PTUI->num_command_line_args;
2682 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2683 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2684 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002685 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002686
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002687 // Set up the initial return values.
2688 if (out_TU)
2689 *out_TU = NULL;
2690 PTUI->result = CXError_Failure;
2691
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002692 // Check arguments.
2693 if (!CIdx || !out_TU ||
2694 (unsaved_files == NULL && num_unsaved_files != 0)) {
2695 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002696 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002697 }
2698
Guy Benyei11169dd2012-12-18 14:30:41 +00002699 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2700
2701 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2702 setThreadBackgroundPriority();
2703
2704 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2705 // FIXME: Add a flag for modules.
2706 TranslationUnitKind TUKind
2707 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002708 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002709 = options & CXTranslationUnit_CacheCompletionResults;
2710 bool IncludeBriefCommentsInCodeCompletion
2711 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2712 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2713 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2714
2715 // Configure the diagnostics.
2716 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002717 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002718
2719 // Recover resources if we crash before exiting this function.
2720 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2721 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2722 DiagCleanup(Diags.getPtr());
2723
Ahmed Charlesb8984322014-03-07 20:03:18 +00002724 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2725 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002726
2727 // Recover resources if we crash before exiting this function.
2728 llvm::CrashRecoveryContextCleanupRegistrar<
2729 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2730
2731 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2732 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2733 const llvm::MemoryBuffer *Buffer
2734 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2735 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2736 Buffer));
2737 }
2738
Ahmed Charlesb8984322014-03-07 20:03:18 +00002739 std::unique_ptr<std::vector<const char *>> Args(
2740 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002741
2742 // Recover resources if we crash before exiting this method.
2743 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2744 ArgsCleanup(Args.get());
2745
2746 // Since the Clang C library is primarily used by batch tools dealing with
2747 // (often very broken) source code, where spell-checking can have a
2748 // significant negative impact on performance (particularly when
2749 // precompiled headers are involved), we disable it by default.
2750 // Only do this if we haven't found a spell-checking-related argument.
2751 bool FoundSpellCheckingArgument = false;
2752 for (int I = 0; I != num_command_line_args; ++I) {
2753 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2754 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2755 FoundSpellCheckingArgument = true;
2756 break;
2757 }
2758 }
2759 if (!FoundSpellCheckingArgument)
2760 Args->push_back("-fno-spell-checking");
2761
2762 Args->insert(Args->end(), command_line_args,
2763 command_line_args + num_command_line_args);
2764
2765 // The 'source_filename' argument is optional. If the caller does not
2766 // specify it then it is assumed that the source file is specified
2767 // in the actual argument list.
2768 // Put the source file after command_line_args otherwise if '-x' flag is
2769 // present it will be unused.
2770 if (source_filename)
2771 Args->push_back(source_filename);
2772
2773 // Do we need the detailed preprocessing record?
2774 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2775 Args->push_back("-Xclang");
2776 Args->push_back("-detailed-preprocessing-record");
2777 }
2778
2779 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002780 std::unique_ptr<ASTUnit> ErrUnit;
2781 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002782 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002783 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2784 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2785 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2786 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2787 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2788 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002789
2790 if (NumErrors != Diags->getClient()->getNumErrors()) {
2791 // Make sure to check that 'Unit' is non-NULL.
2792 if (CXXIdx->getDisplayDiagnostics())
2793 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2794 }
2795
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002796 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2797 PTUI->result = CXError_ASTReadError;
2798 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002799 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002800 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2801 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002802}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002803
2804CXTranslationUnit
2805clang_parseTranslationUnit(CXIndex CIdx,
2806 const char *source_filename,
2807 const char *const *command_line_args,
2808 int num_command_line_args,
2809 struct CXUnsavedFile *unsaved_files,
2810 unsigned num_unsaved_files,
2811 unsigned options) {
2812 CXTranslationUnit TU;
2813 enum CXErrorCode Result = clang_parseTranslationUnit2(
2814 CIdx, source_filename, command_line_args, num_command_line_args,
2815 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002816 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002817 assert((TU && Result == CXError_Success) ||
2818 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002819 return TU;
2820}
2821
2822enum CXErrorCode clang_parseTranslationUnit2(
2823 CXIndex CIdx,
2824 const char *source_filename,
2825 const char *const *command_line_args,
2826 int num_command_line_args,
2827 struct CXUnsavedFile *unsaved_files,
2828 unsigned num_unsaved_files,
2829 unsigned options,
2830 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002831 LOG_FUNC_SECTION {
2832 *Log << source_filename << ": ";
2833 for (int i = 0; i != num_command_line_args; ++i)
2834 *Log << command_line_args[i] << " ";
2835 }
2836
Guy Benyei11169dd2012-12-18 14:30:41 +00002837 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2838 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002839 num_unsaved_files, options, out_TU,
2840 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002841 llvm::CrashRecoveryContext CRC;
2842
2843 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2844 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2845 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2846 fprintf(stderr, " 'command_line_args' : [");
2847 for (int i = 0; i != num_command_line_args; ++i) {
2848 if (i)
2849 fprintf(stderr, ", ");
2850 fprintf(stderr, "'%s'", command_line_args[i]);
2851 }
2852 fprintf(stderr, "],\n");
2853 fprintf(stderr, " 'unsaved_files' : [");
2854 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2855 if (i)
2856 fprintf(stderr, ", ");
2857 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2858 unsaved_files[i].Length);
2859 }
2860 fprintf(stderr, "],\n");
2861 fprintf(stderr, " 'options' : %d,\n", options);
2862 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002863
2864 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002865 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002866 if (CXTranslationUnit *TU = PTUI.out_TU)
2867 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002868 }
2869
2870 return PTUI.result;
2871}
2872
2873unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2874 return CXSaveTranslationUnit_None;
2875}
2876
2877namespace {
2878
2879struct SaveTranslationUnitInfo {
2880 CXTranslationUnit TU;
2881 const char *FileName;
2882 unsigned options;
2883 CXSaveError result;
2884};
2885
2886}
2887
2888static void clang_saveTranslationUnit_Impl(void *UserData) {
2889 SaveTranslationUnitInfo *STUI =
2890 static_cast<SaveTranslationUnitInfo*>(UserData);
2891
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002892 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002893 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2894 setThreadBackgroundPriority();
2895
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002896 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002897 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2898}
2899
2900int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2901 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002902 LOG_FUNC_SECTION {
2903 *Log << TU << ' ' << FileName;
2904 }
2905
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002906 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002907 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002908 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002909 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002910
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002911 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002912 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2913 if (!CXXUnit->hasSema())
2914 return CXSaveError_InvalidTU;
2915
2916 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2917
2918 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2919 getenv("LIBCLANG_NOTHREADS")) {
2920 clang_saveTranslationUnit_Impl(&STUI);
2921
2922 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2923 PrintLibclangResourceUsage(TU);
2924
2925 return STUI.result;
2926 }
2927
2928 // We have an AST that has invalid nodes due to compiler errors.
2929 // Use a crash recovery thread for protection.
2930
2931 llvm::CrashRecoveryContext CRC;
2932
2933 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2934 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2935 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2936 fprintf(stderr, " 'options' : %d,\n", options);
2937 fprintf(stderr, "}\n");
2938
2939 return CXSaveError_Unknown;
2940
2941 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2942 PrintLibclangResourceUsage(TU);
2943 }
2944
2945 return STUI.result;
2946}
2947
2948void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2949 if (CTUnit) {
2950 // If the translation unit has been marked as unsafe to free, just discard
2951 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002952 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2953 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002954 return;
2955
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002956 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002957 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002958 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2959 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002960 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002961 delete CTUnit;
2962 }
2963}
2964
2965unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2966 return CXReparse_None;
2967}
2968
2969struct ReparseTranslationUnitInfo {
2970 CXTranslationUnit TU;
2971 unsigned num_unsaved_files;
2972 struct CXUnsavedFile *unsaved_files;
2973 unsigned options;
2974 int result;
2975};
2976
2977static void clang_reparseTranslationUnit_Impl(void *UserData) {
2978 ReparseTranslationUnitInfo *RTUI =
2979 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002980 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002981
Guy Benyei11169dd2012-12-18 14:30:41 +00002982 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002983 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2984 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2985 unsigned options = RTUI->options;
2986 (void) options;
2987
2988 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002989 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002990 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002991 RTUI->result = CXError_InvalidArguments;
2992 return;
2993 }
2994 if (unsaved_files == NULL && num_unsaved_files != 0) {
2995 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00002996 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002997 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002998
2999 // Reset the associated diagnostics.
3000 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3001 TU->Diagnostics = 0;
3002
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003003 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003004 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3005 setThreadBackgroundPriority();
3006
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003007 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003008 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003009
3010 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3011 new std::vector<ASTUnit::RemappedFile>());
3012
Guy Benyei11169dd2012-12-18 14:30:41 +00003013 // Recover resources if we crash before exiting this function.
3014 llvm::CrashRecoveryContextCleanupRegistrar<
3015 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3016
3017 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3018 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3019 const llvm::MemoryBuffer *Buffer
3020 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3021 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3022 Buffer));
3023 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003024
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003025 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003026 RTUI->result = CXError_Success;
3027 else if (isASTReadError(CXXUnit))
3028 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003029}
3030
3031int clang_reparseTranslationUnit(CXTranslationUnit TU,
3032 unsigned num_unsaved_files,
3033 struct CXUnsavedFile *unsaved_files,
3034 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003035 LOG_FUNC_SECTION {
3036 *Log << TU;
3037 }
3038
Guy Benyei11169dd2012-12-18 14:30:41 +00003039 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003040 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003041
3042 if (getenv("LIBCLANG_NOTHREADS")) {
3043 clang_reparseTranslationUnit_Impl(&RTUI);
3044 return RTUI.result;
3045 }
3046
3047 llvm::CrashRecoveryContext CRC;
3048
3049 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3050 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003051 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003052 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003053 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3054 PrintLibclangResourceUsage(TU);
3055
3056 return RTUI.result;
3057}
3058
3059
3060CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003061 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003062 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003063 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003064 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003065
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003066 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003067 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003068}
3069
3070CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003071 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003072 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003073 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003074 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003075
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003076 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003077 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3078}
3079
3080} // end: extern "C"
3081
3082//===----------------------------------------------------------------------===//
3083// CXFile Operations.
3084//===----------------------------------------------------------------------===//
3085
3086extern "C" {
3087CXString clang_getFileName(CXFile SFile) {
3088 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003089 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003090
3091 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003092 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003093}
3094
3095time_t clang_getFileTime(CXFile SFile) {
3096 if (!SFile)
3097 return 0;
3098
3099 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3100 return FEnt->getModificationTime();
3101}
3102
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003103CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003104 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003105 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003106 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003107 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003108
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003109 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003110
3111 FileManager &FMgr = CXXUnit->getFileManager();
3112 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3113}
3114
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003115unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3116 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003117 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003118 LOG_BAD_TU(TU);
3119 return 0;
3120 }
3121
3122 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003123 return 0;
3124
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003125 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003126 FileEntry *FEnt = static_cast<FileEntry *>(file);
3127 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3128 .isFileMultipleIncludeGuarded(FEnt);
3129}
3130
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003131int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3132 if (!file || !outID)
3133 return 1;
3134
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003135 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003136 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3137 outID->data[0] = ID.getDevice();
3138 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003139 outID->data[2] = FEnt->getModificationTime();
3140 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003141}
3142
Guy Benyei11169dd2012-12-18 14:30:41 +00003143} // end: extern "C"
3144
3145//===----------------------------------------------------------------------===//
3146// CXCursor Operations.
3147//===----------------------------------------------------------------------===//
3148
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003149static const Decl *getDeclFromExpr(const Stmt *E) {
3150 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003151 return getDeclFromExpr(CE->getSubExpr());
3152
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003153 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003154 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003155 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003156 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003157 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003158 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003159 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003160 if (PRE->isExplicitProperty())
3161 return PRE->getExplicitProperty();
3162 // It could be messaging both getter and setter as in:
3163 // ++myobj.myprop;
3164 // in which case prefer to associate the setter since it is less obvious
3165 // from inspecting the source that the setter is going to get called.
3166 if (PRE->isMessagingSetter())
3167 return PRE->getImplicitPropertySetter();
3168 return PRE->getImplicitPropertyGetter();
3169 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003170 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003171 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003172 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003173 if (Expr *Src = OVE->getSourceExpr())
3174 return getDeclFromExpr(Src);
3175
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003176 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003177 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003178 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003179 if (!CE->isElidable())
3180 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003181 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003182 return OME->getMethodDecl();
3183
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003184 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003185 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003186 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003187 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3188 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003189 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003190 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3191 isa<ParmVarDecl>(SizeOfPack->getPack()))
3192 return SizeOfPack->getPack();
3193
3194 return 0;
3195}
3196
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003197static SourceLocation getLocationFromExpr(const Expr *E) {
3198 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003199 return getLocationFromExpr(CE->getSubExpr());
3200
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003201 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003202 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003203 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003204 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003205 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003206 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003207 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003208 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003209 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003210 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003211 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003212 return PropRef->getLocation();
3213
3214 return E->getLocStart();
3215}
3216
3217extern "C" {
3218
3219unsigned clang_visitChildren(CXCursor parent,
3220 CXCursorVisitor visitor,
3221 CXClientData client_data) {
3222 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3223 /*VisitPreprocessorLast=*/false);
3224 return CursorVis.VisitChildren(parent);
3225}
3226
3227#ifndef __has_feature
3228#define __has_feature(x) 0
3229#endif
3230#if __has_feature(blocks)
3231typedef enum CXChildVisitResult
3232 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3233
3234static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3235 CXClientData client_data) {
3236 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3237 return block(cursor, parent);
3238}
3239#else
3240// If we are compiled with a compiler that doesn't have native blocks support,
3241// define and call the block manually, so the
3242typedef struct _CXChildVisitResult
3243{
3244 void *isa;
3245 int flags;
3246 int reserved;
3247 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3248 CXCursor);
3249} *CXCursorVisitorBlock;
3250
3251static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3252 CXClientData client_data) {
3253 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3254 return block->invoke(block, cursor, parent);
3255}
3256#endif
3257
3258
3259unsigned clang_visitChildrenWithBlock(CXCursor parent,
3260 CXCursorVisitorBlock block) {
3261 return clang_visitChildren(parent, visitWithBlock, block);
3262}
3263
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003264static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003265 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003266 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003267
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003268 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003269 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003270 if (const ObjCPropertyImplDecl *PropImpl =
3271 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003272 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003273 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003274
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003275 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003276 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003277 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003278
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003279 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003280 }
3281
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003282 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003283 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003284
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003285 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003286 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3287 // and returns different names. NamedDecl returns the class name and
3288 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003289 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003290
3291 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003292 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003293
3294 SmallString<1024> S;
3295 llvm::raw_svector_ostream os(S);
3296 ND->printName(os);
3297
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003298 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003299}
3300
3301CXString clang_getCursorSpelling(CXCursor C) {
3302 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003303 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003304
3305 if (clang_isReference(C.kind)) {
3306 switch (C.kind) {
3307 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003308 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003309 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003310 }
3311 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003312 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003313 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003314 }
3315 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003316 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003317 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003318 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003319 }
3320 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003321 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003322 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003323 }
3324 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003325 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003326 assert(Type && "Missing type decl");
3327
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003328 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003329 getAsString());
3330 }
3331 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003332 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003333 assert(Template && "Missing template decl");
3334
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003335 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003336 }
3337
3338 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003339 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003340 assert(NS && "Missing namespace decl");
3341
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003342 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003343 }
3344
3345 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003346 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003347 assert(Field && "Missing member decl");
3348
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003349 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003350 }
3351
3352 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003353 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003354 assert(Label && "Missing label");
3355
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003356 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003357 }
3358
3359 case CXCursor_OverloadedDeclRef: {
3360 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003361 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3362 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003363 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003364 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003365 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003366 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003367 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003368 OverloadedTemplateStorage *Ovl
3369 = Storage.get<OverloadedTemplateStorage*>();
3370 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003371 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003372 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 }
3374
3375 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003376 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003377 assert(Var && "Missing variable decl");
3378
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003379 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 }
3381
3382 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003383 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 }
3385 }
3386
3387 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003388 const Expr *E = getCursorExpr(C);
3389
3390 if (C.kind == CXCursor_ObjCStringLiteral ||
3391 C.kind == CXCursor_StringLiteral) {
3392 const StringLiteral *SLit;
3393 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3394 SLit = OSL->getString();
3395 } else {
3396 SLit = cast<StringLiteral>(E);
3397 }
3398 SmallString<256> Buf;
3399 llvm::raw_svector_ostream OS(Buf);
3400 SLit->outputString(OS);
3401 return cxstring::createDup(OS.str());
3402 }
3403
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003404 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003405 if (D)
3406 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003407 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003408 }
3409
3410 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003411 const Stmt *S = getCursorStmt(C);
3412 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003413 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003414
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003415 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003416 }
3417
3418 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003419 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003420 ->getNameStart());
3421
3422 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003423 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003424 ->getNameStart());
3425
3426 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003427 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003428
3429 if (clang_isDeclaration(C.kind))
3430 return getDeclSpelling(getCursorDecl(C));
3431
3432 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003433 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003434 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003435 }
3436
3437 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003438 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003439 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003440 }
3441
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003442 if (C.kind == CXCursor_PackedAttr) {
3443 return cxstring::createRef("packed");
3444 }
3445
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003446 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003447}
3448
3449CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3450 unsigned pieceIndex,
3451 unsigned options) {
3452 if (clang_Cursor_isNull(C))
3453 return clang_getNullRange();
3454
3455 ASTContext &Ctx = getCursorContext(C);
3456
3457 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003458 const Stmt *S = getCursorStmt(C);
3459 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003460 if (pieceIndex > 0)
3461 return clang_getNullRange();
3462 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3463 }
3464
3465 return clang_getNullRange();
3466 }
3467
3468 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003469 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003470 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3471 if (pieceIndex >= ME->getNumSelectorLocs())
3472 return clang_getNullRange();
3473 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3474 }
3475 }
3476
3477 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3478 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003479 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003480 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3481 if (pieceIndex >= MD->getNumSelectorLocs())
3482 return clang_getNullRange();
3483 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3484 }
3485 }
3486
3487 if (C.kind == CXCursor_ObjCCategoryDecl ||
3488 C.kind == CXCursor_ObjCCategoryImplDecl) {
3489 if (pieceIndex > 0)
3490 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003491 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003492 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3493 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003494 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003495 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3496 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3497 }
3498
3499 if (C.kind == CXCursor_ModuleImportDecl) {
3500 if (pieceIndex > 0)
3501 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003502 if (const ImportDecl *ImportD =
3503 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003504 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3505 if (!Locs.empty())
3506 return cxloc::translateSourceRange(Ctx,
3507 SourceRange(Locs.front(), Locs.back()));
3508 }
3509 return clang_getNullRange();
3510 }
3511
3512 // FIXME: A CXCursor_InclusionDirective should give the location of the
3513 // filename, but we don't keep track of this.
3514
3515 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3516 // but we don't keep track of this.
3517
3518 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3519 // but we don't keep track of this.
3520
3521 // Default handling, give the location of the cursor.
3522
3523 if (pieceIndex > 0)
3524 return clang_getNullRange();
3525
3526 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3527 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3528 return cxloc::translateSourceRange(Ctx, Loc);
3529}
3530
3531CXString clang_getCursorDisplayName(CXCursor C) {
3532 if (!clang_isDeclaration(C.kind))
3533 return clang_getCursorSpelling(C);
3534
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003535 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003536 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003537 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003538
3539 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003540 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003541 D = FunTmpl->getTemplatedDecl();
3542
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003543 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003544 SmallString<64> Str;
3545 llvm::raw_svector_ostream OS(Str);
3546 OS << *Function;
3547 if (Function->getPrimaryTemplate())
3548 OS << "<>";
3549 OS << "(";
3550 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3551 if (I)
3552 OS << ", ";
3553 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3554 }
3555
3556 if (Function->isVariadic()) {
3557 if (Function->getNumParams())
3558 OS << ", ";
3559 OS << "...";
3560 }
3561 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003562 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003563 }
3564
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003565 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003566 SmallString<64> Str;
3567 llvm::raw_svector_ostream OS(Str);
3568 OS << *ClassTemplate;
3569 OS << "<";
3570 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3571 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3572 if (I)
3573 OS << ", ";
3574
3575 NamedDecl *Param = Params->getParam(I);
3576 if (Param->getIdentifier()) {
3577 OS << Param->getIdentifier()->getName();
3578 continue;
3579 }
3580
3581 // There is no parameter name, which makes this tricky. Try to come up
3582 // with something useful that isn't too long.
3583 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3584 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3585 else if (NonTypeTemplateParmDecl *NTTP
3586 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3587 OS << NTTP->getType().getAsString(Policy);
3588 else
3589 OS << "template<...> class";
3590 }
3591
3592 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003593 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003594 }
3595
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003596 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003597 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3598 // If the type was explicitly written, use that.
3599 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003600 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003601
Benjamin Kramer9170e912013-02-22 15:46:01 +00003602 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003603 llvm::raw_svector_ostream OS(Str);
3604 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003605 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003606 ClassSpec->getTemplateArgs().data(),
3607 ClassSpec->getTemplateArgs().size(),
3608 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003609 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 }
3611
3612 return clang_getCursorSpelling(C);
3613}
3614
3615CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3616 switch (Kind) {
3617 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003618 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003619 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003620 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003621 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003622 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003624 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003626 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003628 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003630 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003632 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003633 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003634 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003636 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003638 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003639 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003640 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003642 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003643 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003644 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003646 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003648 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003650 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003652 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003654 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003656 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003658 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003660 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003662 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003664 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003666 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003668 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003670 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003672 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003745 case CXCursor_ObjCSelfExpr:
3746 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003863 case CXCursor_PackedAttr:
3864 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003910 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003913 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003914 return cxstring::createRef("OMPParallelDirective");
3915 case CXCursor_OMPSimdDirective:
3916 return cxstring::createRef("OMPSimdDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 }
3918
3919 llvm_unreachable("Unhandled CXCursorKind");
3920}
3921
3922struct GetCursorData {
3923 SourceLocation TokenBeginLoc;
3924 bool PointsAtMacroArgExpansion;
3925 bool VisitedObjCPropertyImplDecl;
3926 SourceLocation VisitedDeclaratorDeclStartLoc;
3927 CXCursor &BestCursor;
3928
3929 GetCursorData(SourceManager &SM,
3930 SourceLocation tokenBegin, CXCursor &outputCursor)
3931 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3932 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3933 VisitedObjCPropertyImplDecl = false;
3934 }
3935};
3936
3937static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3938 CXCursor parent,
3939 CXClientData client_data) {
3940 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3941 CXCursor *BestCursor = &Data->BestCursor;
3942
3943 // If we point inside a macro argument we should provide info of what the
3944 // token is so use the actual cursor, don't replace it with a macro expansion
3945 // cursor.
3946 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3947 return CXChildVisit_Recurse;
3948
3949 if (clang_isDeclaration(cursor.kind)) {
3950 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003951 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003952 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3953 if (MD->isImplicit())
3954 return CXChildVisit_Break;
3955
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003956 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3958 // Check that when we have multiple @class references in the same line,
3959 // that later ones do not override the previous ones.
3960 // If we have:
3961 // @class Foo, Bar;
3962 // source ranges for both start at '@', so 'Bar' will end up overriding
3963 // 'Foo' even though the cursor location was at 'Foo'.
3964 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3965 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003966 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003967 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3968 if (PrevID != ID &&
3969 !PrevID->isThisDeclarationADefinition() &&
3970 !ID->isThisDeclarationADefinition())
3971 return CXChildVisit_Break;
3972 }
3973
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003974 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003975 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3976 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3977 // Check that when we have multiple declarators in the same line,
3978 // that later ones do not override the previous ones.
3979 // If we have:
3980 // int Foo, Bar;
3981 // source ranges for both start at 'int', so 'Bar' will end up overriding
3982 // 'Foo' even though the cursor location was at 'Foo'.
3983 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3984 return CXChildVisit_Break;
3985 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3986
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003987 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3989 (void)PropImp;
3990 // Check that when we have multiple @synthesize in the same line,
3991 // that later ones do not override the previous ones.
3992 // If we have:
3993 // @synthesize Foo, Bar;
3994 // source ranges for both start at '@', so 'Bar' will end up overriding
3995 // 'Foo' even though the cursor location was at 'Foo'.
3996 if (Data->VisitedObjCPropertyImplDecl)
3997 return CXChildVisit_Break;
3998 Data->VisitedObjCPropertyImplDecl = true;
3999 }
4000 }
4001
4002 if (clang_isExpression(cursor.kind) &&
4003 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004004 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004005 // Avoid having the cursor of an expression replace the declaration cursor
4006 // when the expression source range overlaps the declaration range.
4007 // This can happen for C++ constructor expressions whose range generally
4008 // include the variable declaration, e.g.:
4009 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4010 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4011 D->getLocation() == Data->TokenBeginLoc)
4012 return CXChildVisit_Break;
4013 }
4014 }
4015
4016 // If our current best cursor is the construction of a temporary object,
4017 // don't replace that cursor with a type reference, because we want
4018 // clang_getCursor() to point at the constructor.
4019 if (clang_isExpression(BestCursor->kind) &&
4020 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4021 cursor.kind == CXCursor_TypeRef) {
4022 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4023 // as having the actual point on the type reference.
4024 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4025 return CXChildVisit_Recurse;
4026 }
4027
4028 *BestCursor = cursor;
4029 return CXChildVisit_Recurse;
4030}
4031
4032CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004033 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004034 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004035 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004036 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004037
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004038 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4040
4041 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4042 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4043
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004044 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004045 CXFile SearchFile;
4046 unsigned SearchLine, SearchColumn;
4047 CXFile ResultFile;
4048 unsigned ResultLine, ResultColumn;
4049 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4050 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4051 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4052
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004053 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4054 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 &ResultColumn, 0);
4056 SearchFileName = clang_getFileName(SearchFile);
4057 ResultFileName = clang_getFileName(ResultFile);
4058 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4059 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004060 *Log << llvm::format("(%s:%d:%d) = %s",
4061 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4062 clang_getCString(KindSpelling))
4063 << llvm::format("(%s:%d:%d):%s%s",
4064 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4065 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 clang_disposeString(SearchFileName);
4067 clang_disposeString(ResultFileName);
4068 clang_disposeString(KindSpelling);
4069 clang_disposeString(USR);
4070
4071 CXCursor Definition = clang_getCursorDefinition(Result);
4072 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4073 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4074 CXString DefinitionKindSpelling
4075 = clang_getCursorKindSpelling(Definition.kind);
4076 CXFile DefinitionFile;
4077 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004078 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 &DefinitionLine, &DefinitionColumn, 0);
4080 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004081 *Log << llvm::format(" -> %s(%s:%d:%d)",
4082 clang_getCString(DefinitionKindSpelling),
4083 clang_getCString(DefinitionFileName),
4084 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 clang_disposeString(DefinitionFileName);
4086 clang_disposeString(DefinitionKindSpelling);
4087 }
4088 }
4089
4090 return Result;
4091}
4092
4093CXCursor clang_getNullCursor(void) {
4094 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4095}
4096
4097unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004098 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4099 // can't set consistently. For example, when visiting a DeclStmt we will set
4100 // it but we don't set it on the result of clang_getCursorDefinition for
4101 // a reference of the same declaration.
4102 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4103 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4104 // to provide that kind of info.
4105 if (clang_isDeclaration(X.kind))
4106 X.data[1] = 0;
4107 if (clang_isDeclaration(Y.kind))
4108 Y.data[1] = 0;
4109
Guy Benyei11169dd2012-12-18 14:30:41 +00004110 return X == Y;
4111}
4112
4113unsigned clang_hashCursor(CXCursor C) {
4114 unsigned Index = 0;
4115 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4116 Index = 1;
4117
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004118 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004119 std::make_pair(C.kind, C.data[Index]));
4120}
4121
4122unsigned clang_isInvalid(enum CXCursorKind K) {
4123 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4124}
4125
4126unsigned clang_isDeclaration(enum CXCursorKind K) {
4127 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4128 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4129}
4130
4131unsigned clang_isReference(enum CXCursorKind K) {
4132 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4133}
4134
4135unsigned clang_isExpression(enum CXCursorKind K) {
4136 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4137}
4138
4139unsigned clang_isStatement(enum CXCursorKind K) {
4140 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4141}
4142
4143unsigned clang_isAttribute(enum CXCursorKind K) {
4144 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4145}
4146
4147unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4148 return K == CXCursor_TranslationUnit;
4149}
4150
4151unsigned clang_isPreprocessing(enum CXCursorKind K) {
4152 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4153}
4154
4155unsigned clang_isUnexposed(enum CXCursorKind K) {
4156 switch (K) {
4157 case CXCursor_UnexposedDecl:
4158 case CXCursor_UnexposedExpr:
4159 case CXCursor_UnexposedStmt:
4160 case CXCursor_UnexposedAttr:
4161 return true;
4162 default:
4163 return false;
4164 }
4165}
4166
4167CXCursorKind clang_getCursorKind(CXCursor C) {
4168 return C.kind;
4169}
4170
4171CXSourceLocation clang_getCursorLocation(CXCursor C) {
4172 if (clang_isReference(C.kind)) {
4173 switch (C.kind) {
4174 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004175 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004176 = getCursorObjCSuperClassRef(C);
4177 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4178 }
4179
4180 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004181 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004182 = getCursorObjCProtocolRef(C);
4183 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4184 }
4185
4186 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004187 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004188 = getCursorObjCClassRef(C);
4189 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4190 }
4191
4192 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004193 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004194 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4195 }
4196
4197 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004198 std::pair<const TemplateDecl *, SourceLocation> P =
4199 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4201 }
4202
4203 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004204 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4206 }
4207
4208 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004209 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4211 }
4212
4213 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004214 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4216 }
4217
4218 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004219 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004220 if (!BaseSpec)
4221 return clang_getNullLocation();
4222
4223 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4224 return cxloc::translateSourceLocation(getCursorContext(C),
4225 TSInfo->getTypeLoc().getBeginLoc());
4226
4227 return cxloc::translateSourceLocation(getCursorContext(C),
4228 BaseSpec->getLocStart());
4229 }
4230
4231 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004232 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004233 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4234 }
4235
4236 case CXCursor_OverloadedDeclRef:
4237 return cxloc::translateSourceLocation(getCursorContext(C),
4238 getCursorOverloadedDeclRef(C).second);
4239
4240 default:
4241 // FIXME: Need a way to enumerate all non-reference cases.
4242 llvm_unreachable("Missed a reference kind");
4243 }
4244 }
4245
4246 if (clang_isExpression(C.kind))
4247 return cxloc::translateSourceLocation(getCursorContext(C),
4248 getLocationFromExpr(getCursorExpr(C)));
4249
4250 if (clang_isStatement(C.kind))
4251 return cxloc::translateSourceLocation(getCursorContext(C),
4252 getCursorStmt(C)->getLocStart());
4253
4254 if (C.kind == CXCursor_PreprocessingDirective) {
4255 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4256 return cxloc::translateSourceLocation(getCursorContext(C), L);
4257 }
4258
4259 if (C.kind == CXCursor_MacroExpansion) {
4260 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004261 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 return cxloc::translateSourceLocation(getCursorContext(C), L);
4263 }
4264
4265 if (C.kind == CXCursor_MacroDefinition) {
4266 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4267 return cxloc::translateSourceLocation(getCursorContext(C), L);
4268 }
4269
4270 if (C.kind == CXCursor_InclusionDirective) {
4271 SourceLocation L
4272 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4273 return cxloc::translateSourceLocation(getCursorContext(C), L);
4274 }
4275
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004276 if (clang_isAttribute(C.kind)) {
4277 SourceLocation L
4278 = cxcursor::getCursorAttr(C)->getLocation();
4279 return cxloc::translateSourceLocation(getCursorContext(C), L);
4280 }
4281
Guy Benyei11169dd2012-12-18 14:30:41 +00004282 if (!clang_isDeclaration(C.kind))
4283 return clang_getNullLocation();
4284
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004285 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004286 if (!D)
4287 return clang_getNullLocation();
4288
4289 SourceLocation Loc = D->getLocation();
4290 // FIXME: Multiple variables declared in a single declaration
4291 // currently lack the information needed to correctly determine their
4292 // ranges when accounting for the type-specifier. We use context
4293 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4294 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004295 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004296 if (!cxcursor::isFirstInDeclGroup(C))
4297 Loc = VD->getLocation();
4298 }
4299
4300 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004301 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004302 Loc = MD->getSelectorStartLoc();
4303
4304 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4305}
4306
4307} // end extern "C"
4308
4309CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4310 assert(TU);
4311
4312 // Guard against an invalid SourceLocation, or we may assert in one
4313 // of the following calls.
4314 if (SLoc.isInvalid())
4315 return clang_getNullCursor();
4316
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004317 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004318
4319 // Translate the given source location to make it point at the beginning of
4320 // the token under the cursor.
4321 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4322 CXXUnit->getASTContext().getLangOpts());
4323
4324 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4325 if (SLoc.isValid()) {
4326 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4327 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4328 /*VisitPreprocessorLast=*/true,
4329 /*VisitIncludedEntities=*/false,
4330 SourceLocation(SLoc));
4331 CursorVis.visitFileRegion();
4332 }
4333
4334 return Result;
4335}
4336
4337static SourceRange getRawCursorExtent(CXCursor C) {
4338 if (clang_isReference(C.kind)) {
4339 switch (C.kind) {
4340 case CXCursor_ObjCSuperClassRef:
4341 return getCursorObjCSuperClassRef(C).second;
4342
4343 case CXCursor_ObjCProtocolRef:
4344 return getCursorObjCProtocolRef(C).second;
4345
4346 case CXCursor_ObjCClassRef:
4347 return getCursorObjCClassRef(C).second;
4348
4349 case CXCursor_TypeRef:
4350 return getCursorTypeRef(C).second;
4351
4352 case CXCursor_TemplateRef:
4353 return getCursorTemplateRef(C).second;
4354
4355 case CXCursor_NamespaceRef:
4356 return getCursorNamespaceRef(C).second;
4357
4358 case CXCursor_MemberRef:
4359 return getCursorMemberRef(C).second;
4360
4361 case CXCursor_CXXBaseSpecifier:
4362 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4363
4364 case CXCursor_LabelRef:
4365 return getCursorLabelRef(C).second;
4366
4367 case CXCursor_OverloadedDeclRef:
4368 return getCursorOverloadedDeclRef(C).second;
4369
4370 case CXCursor_VariableRef:
4371 return getCursorVariableRef(C).second;
4372
4373 default:
4374 // FIXME: Need a way to enumerate all non-reference cases.
4375 llvm_unreachable("Missed a reference kind");
4376 }
4377 }
4378
4379 if (clang_isExpression(C.kind))
4380 return getCursorExpr(C)->getSourceRange();
4381
4382 if (clang_isStatement(C.kind))
4383 return getCursorStmt(C)->getSourceRange();
4384
4385 if (clang_isAttribute(C.kind))
4386 return getCursorAttr(C)->getRange();
4387
4388 if (C.kind == CXCursor_PreprocessingDirective)
4389 return cxcursor::getCursorPreprocessingDirective(C);
4390
4391 if (C.kind == CXCursor_MacroExpansion) {
4392 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004393 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004394 return TU->mapRangeFromPreamble(Range);
4395 }
4396
4397 if (C.kind == CXCursor_MacroDefinition) {
4398 ASTUnit *TU = getCursorASTUnit(C);
4399 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4400 return TU->mapRangeFromPreamble(Range);
4401 }
4402
4403 if (C.kind == CXCursor_InclusionDirective) {
4404 ASTUnit *TU = getCursorASTUnit(C);
4405 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4406 return TU->mapRangeFromPreamble(Range);
4407 }
4408
4409 if (C.kind == CXCursor_TranslationUnit) {
4410 ASTUnit *TU = getCursorASTUnit(C);
4411 FileID MainID = TU->getSourceManager().getMainFileID();
4412 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4413 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4414 return SourceRange(Start, End);
4415 }
4416
4417 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004418 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004419 if (!D)
4420 return SourceRange();
4421
4422 SourceRange R = D->getSourceRange();
4423 // FIXME: Multiple variables declared in a single declaration
4424 // currently lack the information needed to correctly determine their
4425 // ranges when accounting for the type-specifier. We use context
4426 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4427 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004428 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004429 if (!cxcursor::isFirstInDeclGroup(C))
4430 R.setBegin(VD->getLocation());
4431 }
4432 return R;
4433 }
4434 return SourceRange();
4435}
4436
4437/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4438/// the decl-specifier-seq for declarations.
4439static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4440 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004441 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004442 if (!D)
4443 return SourceRange();
4444
4445 SourceRange R = D->getSourceRange();
4446
4447 // Adjust the start of the location for declarations preceded by
4448 // declaration specifiers.
4449 SourceLocation StartLoc;
4450 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4451 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4452 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004453 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004454 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4455 StartLoc = TI->getTypeLoc().getLocStart();
4456 }
4457
4458 if (StartLoc.isValid() && R.getBegin().isValid() &&
4459 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4460 R.setBegin(StartLoc);
4461
4462 // FIXME: Multiple variables declared in a single declaration
4463 // currently lack the information needed to correctly determine their
4464 // ranges when accounting for the type-specifier. We use context
4465 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4466 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004467 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004468 if (!cxcursor::isFirstInDeclGroup(C))
4469 R.setBegin(VD->getLocation());
4470 }
4471
4472 return R;
4473 }
4474
4475 return getRawCursorExtent(C);
4476}
4477
4478extern "C" {
4479
4480CXSourceRange clang_getCursorExtent(CXCursor C) {
4481 SourceRange R = getRawCursorExtent(C);
4482 if (R.isInvalid())
4483 return clang_getNullRange();
4484
4485 return cxloc::translateSourceRange(getCursorContext(C), R);
4486}
4487
4488CXCursor clang_getCursorReferenced(CXCursor C) {
4489 if (clang_isInvalid(C.kind))
4490 return clang_getNullCursor();
4491
4492 CXTranslationUnit tu = getCursorTU(C);
4493 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004494 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004495 if (!D)
4496 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004497 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004498 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004499 if (const ObjCPropertyImplDecl *PropImpl =
4500 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004501 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4502 return MakeCXCursor(Property, tu);
4503
4504 return C;
4505 }
4506
4507 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004508 const Expr *E = getCursorExpr(C);
4509 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004510 if (D) {
4511 CXCursor declCursor = MakeCXCursor(D, tu);
4512 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4513 declCursor);
4514 return declCursor;
4515 }
4516
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004517 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004518 return MakeCursorOverloadedDeclRef(Ovl, tu);
4519
4520 return clang_getNullCursor();
4521 }
4522
4523 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004524 const Stmt *S = getCursorStmt(C);
4525 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004526 if (LabelDecl *label = Goto->getLabel())
4527 if (LabelStmt *labelS = label->getStmt())
4528 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4529
4530 return clang_getNullCursor();
4531 }
4532
4533 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004534 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004535 return MakeMacroDefinitionCursor(Def, tu);
4536 }
4537
4538 if (!clang_isReference(C.kind))
4539 return clang_getNullCursor();
4540
4541 switch (C.kind) {
4542 case CXCursor_ObjCSuperClassRef:
4543 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4544
4545 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004546 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4547 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004548 return MakeCXCursor(Def, tu);
4549
4550 return MakeCXCursor(Prot, tu);
4551 }
4552
4553 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004554 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4555 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004556 return MakeCXCursor(Def, tu);
4557
4558 return MakeCXCursor(Class, tu);
4559 }
4560
4561 case CXCursor_TypeRef:
4562 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4563
4564 case CXCursor_TemplateRef:
4565 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4566
4567 case CXCursor_NamespaceRef:
4568 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4569
4570 case CXCursor_MemberRef:
4571 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4572
4573 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004574 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004575 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4576 tu ));
4577 }
4578
4579 case CXCursor_LabelRef:
4580 // FIXME: We end up faking the "parent" declaration here because we
4581 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004582 return MakeCXCursor(getCursorLabelRef(C).first,
4583 cxtu::getASTUnit(tu)->getASTContext()
4584 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 tu);
4586
4587 case CXCursor_OverloadedDeclRef:
4588 return C;
4589
4590 case CXCursor_VariableRef:
4591 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4592
4593 default:
4594 // We would prefer to enumerate all non-reference cursor kinds here.
4595 llvm_unreachable("Unhandled reference cursor kind");
4596 }
4597}
4598
4599CXCursor clang_getCursorDefinition(CXCursor C) {
4600 if (clang_isInvalid(C.kind))
4601 return clang_getNullCursor();
4602
4603 CXTranslationUnit TU = getCursorTU(C);
4604
4605 bool WasReference = false;
4606 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4607 C = clang_getCursorReferenced(C);
4608 WasReference = true;
4609 }
4610
4611 if (C.kind == CXCursor_MacroExpansion)
4612 return clang_getCursorReferenced(C);
4613
4614 if (!clang_isDeclaration(C.kind))
4615 return clang_getNullCursor();
4616
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004617 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004618 if (!D)
4619 return clang_getNullCursor();
4620
4621 switch (D->getKind()) {
4622 // Declaration kinds that don't really separate the notions of
4623 // declaration and definition.
4624 case Decl::Namespace:
4625 case Decl::Typedef:
4626 case Decl::TypeAlias:
4627 case Decl::TypeAliasTemplate:
4628 case Decl::TemplateTypeParm:
4629 case Decl::EnumConstant:
4630 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004631 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004632 case Decl::IndirectField:
4633 case Decl::ObjCIvar:
4634 case Decl::ObjCAtDefsField:
4635 case Decl::ImplicitParam:
4636 case Decl::ParmVar:
4637 case Decl::NonTypeTemplateParm:
4638 case Decl::TemplateTemplateParm:
4639 case Decl::ObjCCategoryImpl:
4640 case Decl::ObjCImplementation:
4641 case Decl::AccessSpec:
4642 case Decl::LinkageSpec:
4643 case Decl::ObjCPropertyImpl:
4644 case Decl::FileScopeAsm:
4645 case Decl::StaticAssert:
4646 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004647 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004648 case Decl::Label: // FIXME: Is this right??
4649 case Decl::ClassScopeFunctionSpecialization:
4650 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004651 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004652 return C;
4653
4654 // Declaration kinds that don't make any sense here, but are
4655 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004656 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004657 case Decl::TranslationUnit:
4658 break;
4659
4660 // Declaration kinds for which the definition is not resolvable.
4661 case Decl::UnresolvedUsingTypename:
4662 case Decl::UnresolvedUsingValue:
4663 break;
4664
4665 case Decl::UsingDirective:
4666 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4667 TU);
4668
4669 case Decl::NamespaceAlias:
4670 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4671
4672 case Decl::Enum:
4673 case Decl::Record:
4674 case Decl::CXXRecord:
4675 case Decl::ClassTemplateSpecialization:
4676 case Decl::ClassTemplatePartialSpecialization:
4677 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4678 return MakeCXCursor(Def, TU);
4679 return clang_getNullCursor();
4680
4681 case Decl::Function:
4682 case Decl::CXXMethod:
4683 case Decl::CXXConstructor:
4684 case Decl::CXXDestructor:
4685 case Decl::CXXConversion: {
4686 const FunctionDecl *Def = 0;
4687 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004688 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004689 return clang_getNullCursor();
4690 }
4691
Larisse Voufo39a1e502013-08-06 01:03:05 +00004692 case Decl::Var:
4693 case Decl::VarTemplateSpecialization:
4694 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004695 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004696 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004697 return MakeCXCursor(Def, TU);
4698 return clang_getNullCursor();
4699 }
4700
4701 case Decl::FunctionTemplate: {
4702 const FunctionDecl *Def = 0;
4703 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4704 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4705 return clang_getNullCursor();
4706 }
4707
4708 case Decl::ClassTemplate: {
4709 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4710 ->getDefinition())
4711 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4712 TU);
4713 return clang_getNullCursor();
4714 }
4715
Larisse Voufo39a1e502013-08-06 01:03:05 +00004716 case Decl::VarTemplate: {
4717 if (VarDecl *Def =
4718 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4719 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4720 return clang_getNullCursor();
4721 }
4722
Guy Benyei11169dd2012-12-18 14:30:41 +00004723 case Decl::Using:
4724 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4725 D->getLocation(), TU);
4726
4727 case Decl::UsingShadow:
4728 return clang_getCursorDefinition(
4729 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4730 TU));
4731
4732 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004733 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004734 if (Method->isThisDeclarationADefinition())
4735 return C;
4736
4737 // Dig out the method definition in the associated
4738 // @implementation, if we have it.
4739 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004740 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004741 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4742 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4743 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4744 Method->isInstanceMethod()))
4745 if (Def->isThisDeclarationADefinition())
4746 return MakeCXCursor(Def, TU);
4747
4748 return clang_getNullCursor();
4749 }
4750
4751 case Decl::ObjCCategory:
4752 if (ObjCCategoryImplDecl *Impl
4753 = cast<ObjCCategoryDecl>(D)->getImplementation())
4754 return MakeCXCursor(Impl, TU);
4755 return clang_getNullCursor();
4756
4757 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004758 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004759 return MakeCXCursor(Def, TU);
4760 return clang_getNullCursor();
4761
4762 case Decl::ObjCInterface: {
4763 // There are two notions of a "definition" for an Objective-C
4764 // class: the interface and its implementation. When we resolved a
4765 // reference to an Objective-C class, produce the @interface as
4766 // the definition; when we were provided with the interface,
4767 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004768 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004769 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004770 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004771 return MakeCXCursor(Def, TU);
4772 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4773 return MakeCXCursor(Impl, TU);
4774 return clang_getNullCursor();
4775 }
4776
4777 case Decl::ObjCProperty:
4778 // FIXME: We don't really know where to find the
4779 // ObjCPropertyImplDecls that implement this property.
4780 return clang_getNullCursor();
4781
4782 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004783 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004784 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004785 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004786 return MakeCXCursor(Def, TU);
4787
4788 return clang_getNullCursor();
4789
4790 case Decl::Friend:
4791 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4792 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4793 return clang_getNullCursor();
4794
4795 case Decl::FriendTemplate:
4796 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4797 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4798 return clang_getNullCursor();
4799 }
4800
4801 return clang_getNullCursor();
4802}
4803
4804unsigned clang_isCursorDefinition(CXCursor C) {
4805 if (!clang_isDeclaration(C.kind))
4806 return 0;
4807
4808 return clang_getCursorDefinition(C) == C;
4809}
4810
4811CXCursor clang_getCanonicalCursor(CXCursor C) {
4812 if (!clang_isDeclaration(C.kind))
4813 return C;
4814
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004815 if (const Decl *D = getCursorDecl(C)) {
4816 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004817 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4818 return MakeCXCursor(CatD, getCursorTU(C));
4819
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004820 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4821 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004822 return MakeCXCursor(IFD, getCursorTU(C));
4823
4824 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4825 }
4826
4827 return C;
4828}
4829
4830int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4831 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4832}
4833
4834unsigned clang_getNumOverloadedDecls(CXCursor C) {
4835 if (C.kind != CXCursor_OverloadedDeclRef)
4836 return 0;
4837
4838 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004839 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004840 return E->getNumDecls();
4841
4842 if (OverloadedTemplateStorage *S
4843 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4844 return S->size();
4845
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004846 const Decl *D = Storage.get<const Decl *>();
4847 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004848 return Using->shadow_size();
4849
4850 return 0;
4851}
4852
4853CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4854 if (cursor.kind != CXCursor_OverloadedDeclRef)
4855 return clang_getNullCursor();
4856
4857 if (index >= clang_getNumOverloadedDecls(cursor))
4858 return clang_getNullCursor();
4859
4860 CXTranslationUnit TU = getCursorTU(cursor);
4861 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004862 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004863 return MakeCXCursor(E->decls_begin()[index], TU);
4864
4865 if (OverloadedTemplateStorage *S
4866 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4867 return MakeCXCursor(S->begin()[index], TU);
4868
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004869 const Decl *D = Storage.get<const Decl *>();
4870 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004871 // FIXME: This is, unfortunately, linear time.
4872 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4873 std::advance(Pos, index);
4874 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4875 }
4876
4877 return clang_getNullCursor();
4878}
4879
4880void clang_getDefinitionSpellingAndExtent(CXCursor C,
4881 const char **startBuf,
4882 const char **endBuf,
4883 unsigned *startLine,
4884 unsigned *startColumn,
4885 unsigned *endLine,
4886 unsigned *endColumn) {
4887 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004888 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004889 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4890
4891 SourceManager &SM = FD->getASTContext().getSourceManager();
4892 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4893 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4894 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4895 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4896 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4897 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4898}
4899
4900
4901CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4902 unsigned PieceIndex) {
4903 RefNamePieces Pieces;
4904
4905 switch (C.kind) {
4906 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004907 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004908 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4909 E->getQualifierLoc().getSourceRange());
4910 break;
4911
4912 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004913 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004914 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4915 E->getQualifierLoc().getSourceRange(),
4916 E->getOptionalExplicitTemplateArgs());
4917 break;
4918
4919 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004920 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004921 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004922 const Expr *Callee = OCE->getCallee();
4923 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004924 Callee = ICE->getSubExpr();
4925
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004926 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004927 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4928 DRE->getQualifierLoc().getSourceRange());
4929 }
4930 break;
4931
4932 default:
4933 break;
4934 }
4935
4936 if (Pieces.empty()) {
4937 if (PieceIndex == 0)
4938 return clang_getCursorExtent(C);
4939 } else if (PieceIndex < Pieces.size()) {
4940 SourceRange R = Pieces[PieceIndex];
4941 if (R.isValid())
4942 return cxloc::translateSourceRange(getCursorContext(C), R);
4943 }
4944
4945 return clang_getNullRange();
4946}
4947
4948void clang_enableStackTraces(void) {
4949 llvm::sys::PrintStackTraceOnErrorSignal();
4950}
4951
4952void clang_executeOnThread(void (*fn)(void*), void *user_data,
4953 unsigned stack_size) {
4954 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4955}
4956
4957} // end: extern "C"
4958
4959//===----------------------------------------------------------------------===//
4960// Token-based Operations.
4961//===----------------------------------------------------------------------===//
4962
4963/* CXToken layout:
4964 * int_data[0]: a CXTokenKind
4965 * int_data[1]: starting token location
4966 * int_data[2]: token length
4967 * int_data[3]: reserved
4968 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4969 * otherwise unused.
4970 */
4971extern "C" {
4972
4973CXTokenKind clang_getTokenKind(CXToken CXTok) {
4974 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4975}
4976
4977CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4978 switch (clang_getTokenKind(CXTok)) {
4979 case CXToken_Identifier:
4980 case CXToken_Keyword:
4981 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004982 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004983 ->getNameStart());
4984
4985 case CXToken_Literal: {
4986 // We have stashed the starting pointer in the ptr_data field. Use it.
4987 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004988 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004989 }
4990
4991 case CXToken_Punctuation:
4992 case CXToken_Comment:
4993 break;
4994 }
4995
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004996 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004997 LOG_BAD_TU(TU);
4998 return cxstring::createEmpty();
4999 }
5000
Guy Benyei11169dd2012-12-18 14:30:41 +00005001 // We have to find the starting buffer pointer the hard way, by
5002 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005003 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005004 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005005 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005006
5007 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5008 std::pair<FileID, unsigned> LocInfo
5009 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5010 bool Invalid = false;
5011 StringRef Buffer
5012 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5013 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005014 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005015
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005016 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005017}
5018
5019CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005020 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005021 LOG_BAD_TU(TU);
5022 return clang_getNullLocation();
5023 }
5024
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005025 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005026 if (!CXXUnit)
5027 return clang_getNullLocation();
5028
5029 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5030 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5031}
5032
5033CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005034 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005035 LOG_BAD_TU(TU);
5036 return clang_getNullRange();
5037 }
5038
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005039 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005040 if (!CXXUnit)
5041 return clang_getNullRange();
5042
5043 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5044 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5045}
5046
5047static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5048 SmallVectorImpl<CXToken> &CXTokens) {
5049 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5050 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005051 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005052 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005053 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005054
5055 // Cannot tokenize across files.
5056 if (BeginLocInfo.first != EndLocInfo.first)
5057 return;
5058
5059 // Create a lexer
5060 bool Invalid = false;
5061 StringRef Buffer
5062 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5063 if (Invalid)
5064 return;
5065
5066 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5067 CXXUnit->getASTContext().getLangOpts(),
5068 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5069 Lex.SetCommentRetentionState(true);
5070
5071 // Lex tokens until we hit the end of the range.
5072 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5073 Token Tok;
5074 bool previousWasAt = false;
5075 do {
5076 // Lex the next token
5077 Lex.LexFromRawLexer(Tok);
5078 if (Tok.is(tok::eof))
5079 break;
5080
5081 // Initialize the CXToken.
5082 CXToken CXTok;
5083
5084 // - Common fields
5085 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5086 CXTok.int_data[2] = Tok.getLength();
5087 CXTok.int_data[3] = 0;
5088
5089 // - Kind-specific fields
5090 if (Tok.isLiteral()) {
5091 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005092 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005093 } else if (Tok.is(tok::raw_identifier)) {
5094 // Lookup the identifier to determine whether we have a keyword.
5095 IdentifierInfo *II
5096 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5097
5098 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5099 CXTok.int_data[0] = CXToken_Keyword;
5100 }
5101 else {
5102 CXTok.int_data[0] = Tok.is(tok::identifier)
5103 ? CXToken_Identifier
5104 : CXToken_Keyword;
5105 }
5106 CXTok.ptr_data = II;
5107 } else if (Tok.is(tok::comment)) {
5108 CXTok.int_data[0] = CXToken_Comment;
5109 CXTok.ptr_data = 0;
5110 } else {
5111 CXTok.int_data[0] = CXToken_Punctuation;
5112 CXTok.ptr_data = 0;
5113 }
5114 CXTokens.push_back(CXTok);
5115 previousWasAt = Tok.is(tok::at);
5116 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5117}
5118
5119void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5120 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005121 LOG_FUNC_SECTION {
5122 *Log << TU << ' ' << Range;
5123 }
5124
Guy Benyei11169dd2012-12-18 14:30:41 +00005125 if (Tokens)
5126 *Tokens = 0;
5127 if (NumTokens)
5128 *NumTokens = 0;
5129
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005130 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005131 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005132 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005133 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005134
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005135 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005136 if (!CXXUnit || !Tokens || !NumTokens)
5137 return;
5138
5139 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5140
5141 SourceRange R = cxloc::translateCXSourceRange(Range);
5142 if (R.isInvalid())
5143 return;
5144
5145 SmallVector<CXToken, 32> CXTokens;
5146 getTokens(CXXUnit, R, CXTokens);
5147
5148 if (CXTokens.empty())
5149 return;
5150
5151 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5152 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5153 *NumTokens = CXTokens.size();
5154}
5155
5156void clang_disposeTokens(CXTranslationUnit TU,
5157 CXToken *Tokens, unsigned NumTokens) {
5158 free(Tokens);
5159}
5160
5161} // end: extern "C"
5162
5163//===----------------------------------------------------------------------===//
5164// Token annotation APIs.
5165//===----------------------------------------------------------------------===//
5166
Guy Benyei11169dd2012-12-18 14:30:41 +00005167static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5168 CXCursor parent,
5169 CXClientData client_data);
5170static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5171 CXClientData client_data);
5172
5173namespace {
5174class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005175 CXToken *Tokens;
5176 CXCursor *Cursors;
5177 unsigned NumTokens;
5178 unsigned TokIdx;
5179 unsigned PreprocessingTokIdx;
5180 CursorVisitor AnnotateVis;
5181 SourceManager &SrcMgr;
5182 bool HasContextSensitiveKeywords;
5183
5184 struct PostChildrenInfo {
5185 CXCursor Cursor;
5186 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005187 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005188 unsigned BeforeChildrenTokenIdx;
5189 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005190 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005191
5192 CXToken &getTok(unsigned Idx) {
5193 assert(Idx < NumTokens);
5194 return Tokens[Idx];
5195 }
5196 const CXToken &getTok(unsigned Idx) const {
5197 assert(Idx < NumTokens);
5198 return Tokens[Idx];
5199 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005200 bool MoreTokens() const { return TokIdx < NumTokens; }
5201 unsigned NextToken() const { return TokIdx; }
5202 void AdvanceToken() { ++TokIdx; }
5203 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005204 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005205 }
5206 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005207 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005208 }
5209 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005210 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005211 }
5212
5213 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005214 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005215 SourceRange);
5216
5217public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005218 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005219 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005220 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005221 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005222 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005223 AnnotateTokensVisitor, this,
5224 /*VisitPreprocessorLast=*/true,
5225 /*VisitIncludedEntities=*/false,
5226 RegionOfInterest,
5227 /*VisitDeclsOnly=*/false,
5228 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005229 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005230 HasContextSensitiveKeywords(false) { }
5231
5232 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5233 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5234 bool postVisitChildren(CXCursor cursor);
5235 void AnnotateTokens();
5236
5237 /// \brief Determine whether the annotator saw any cursors that have
5238 /// context-sensitive keywords.
5239 bool hasContextSensitiveKeywords() const {
5240 return HasContextSensitiveKeywords;
5241 }
5242
5243 ~AnnotateTokensWorker() {
5244 assert(PostChildrenInfos.empty());
5245 }
5246};
5247}
5248
5249void AnnotateTokensWorker::AnnotateTokens() {
5250 // Walk the AST within the region of interest, annotating tokens
5251 // along the way.
5252 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005253}
Guy Benyei11169dd2012-12-18 14:30:41 +00005254
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005255static inline void updateCursorAnnotation(CXCursor &Cursor,
5256 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005257 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005258 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005259 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005260}
5261
5262/// \brief It annotates and advances tokens with a cursor until the comparison
5263//// between the cursor location and the source range is the same as
5264/// \arg compResult.
5265///
5266/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5267/// Pass RangeOverlap to annotate tokens inside a range.
5268void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5269 RangeComparisonResult compResult,
5270 SourceRange range) {
5271 while (MoreTokens()) {
5272 const unsigned I = NextToken();
5273 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005274 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5275 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005276
5277 SourceLocation TokLoc = GetTokenLoc(I);
5278 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005279 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005280 AdvanceToken();
5281 continue;
5282 }
5283 break;
5284 }
5285}
5286
5287/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005288/// \returns true if it advanced beyond all macro tokens, false otherwise.
5289bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005290 CXCursor updateC,
5291 RangeComparisonResult compResult,
5292 SourceRange range) {
5293 assert(MoreTokens());
5294 assert(isFunctionMacroToken(NextToken()) &&
5295 "Should be called only for macro arg tokens");
5296
5297 // This works differently than annotateAndAdvanceTokens; because expanded
5298 // macro arguments can have arbitrary translation-unit source order, we do not
5299 // advance the token index one by one until a token fails the range test.
5300 // We only advance once past all of the macro arg tokens if all of them
5301 // pass the range test. If one of them fails we keep the token index pointing
5302 // at the start of the macro arg tokens so that the failing token will be
5303 // annotated by a subsequent annotation try.
5304
5305 bool atLeastOneCompFail = false;
5306
5307 unsigned I = NextToken();
5308 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5309 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5310 if (TokLoc.isFileID())
5311 continue; // not macro arg token, it's parens or comma.
5312 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5313 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5314 Cursors[I] = updateC;
5315 } else
5316 atLeastOneCompFail = true;
5317 }
5318
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005319 if (atLeastOneCompFail)
5320 return false;
5321
5322 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5323 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005324}
5325
5326enum CXChildVisitResult
5327AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005328 SourceRange cursorRange = getRawCursorExtent(cursor);
5329 if (cursorRange.isInvalid())
5330 return CXChildVisit_Recurse;
5331
5332 if (!HasContextSensitiveKeywords) {
5333 // Objective-C properties can have context-sensitive keywords.
5334 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005335 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005336 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5337 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5338 }
5339 // Objective-C methods can have context-sensitive keywords.
5340 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5341 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005342 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005343 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5344 if (Method->getObjCDeclQualifier())
5345 HasContextSensitiveKeywords = true;
5346 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005347 for (const auto *P : Method->params()) {
5348 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005349 HasContextSensitiveKeywords = true;
5350 break;
5351 }
5352 }
5353 }
5354 }
5355 }
5356 // C++ methods can have context-sensitive keywords.
5357 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005358 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005359 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5360 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5361 HasContextSensitiveKeywords = true;
5362 }
5363 }
5364 // C++ classes can have context-sensitive keywords.
5365 else if (cursor.kind == CXCursor_StructDecl ||
5366 cursor.kind == CXCursor_ClassDecl ||
5367 cursor.kind == CXCursor_ClassTemplate ||
5368 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005369 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005370 if (D->hasAttr<FinalAttr>())
5371 HasContextSensitiveKeywords = true;
5372 }
5373 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005374
5375 // Don't override a property annotation with its getter/setter method.
5376 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5377 parent.kind == CXCursor_ObjCPropertyDecl)
5378 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005379
5380 if (clang_isPreprocessing(cursor.kind)) {
5381 // Items in the preprocessing record are kept separate from items in
5382 // declarations, so we keep a separate token index.
5383 unsigned SavedTokIdx = TokIdx;
5384 TokIdx = PreprocessingTokIdx;
5385
5386 // Skip tokens up until we catch up to the beginning of the preprocessing
5387 // entry.
5388 while (MoreTokens()) {
5389 const unsigned I = NextToken();
5390 SourceLocation TokLoc = GetTokenLoc(I);
5391 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5392 case RangeBefore:
5393 AdvanceToken();
5394 continue;
5395 case RangeAfter:
5396 case RangeOverlap:
5397 break;
5398 }
5399 break;
5400 }
5401
5402 // Look at all of the tokens within this range.
5403 while (MoreTokens()) {
5404 const unsigned I = NextToken();
5405 SourceLocation TokLoc = GetTokenLoc(I);
5406 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5407 case RangeBefore:
5408 llvm_unreachable("Infeasible");
5409 case RangeAfter:
5410 break;
5411 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005412 // For macro expansions, just note where the beginning of the macro
5413 // expansion occurs.
5414 if (cursor.kind == CXCursor_MacroExpansion) {
5415 if (TokLoc == cursorRange.getBegin())
5416 Cursors[I] = cursor;
5417 AdvanceToken();
5418 break;
5419 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005420 // We may have already annotated macro names inside macro definitions.
5421 if (Cursors[I].kind != CXCursor_MacroExpansion)
5422 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005423 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005424 continue;
5425 }
5426 break;
5427 }
5428
5429 // Save the preprocessing token index; restore the non-preprocessing
5430 // token index.
5431 PreprocessingTokIdx = TokIdx;
5432 TokIdx = SavedTokIdx;
5433 return CXChildVisit_Recurse;
5434 }
5435
5436 if (cursorRange.isInvalid())
5437 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005438
5439 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005440 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005441 const enum CXCursorKind K = clang_getCursorKind(parent);
5442 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005443 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5444 // Attributes are annotated out-of-order, skip tokens until we reach it.
5445 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005446 ? clang_getNullCursor() : parent;
5447
5448 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5449
5450 // Avoid having the cursor of an expression "overwrite" the annotation of the
5451 // variable declaration that it belongs to.
5452 // This can happen for C++ constructor expressions whose range generally
5453 // include the variable declaration, e.g.:
5454 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005455 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005456 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005457 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005458 const unsigned I = NextToken();
5459 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5460 E->getLocStart() == D->getLocation() &&
5461 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005462 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005463 AdvanceToken();
5464 }
5465 }
5466 }
5467
5468 // Before recursing into the children keep some state that we are going
5469 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5470 // extra work after the child nodes are visited.
5471 // Note that we don't call VisitChildren here to avoid traversing statements
5472 // code-recursively which can blow the stack.
5473
5474 PostChildrenInfo Info;
5475 Info.Cursor = cursor;
5476 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005477 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005478 Info.BeforeChildrenTokenIdx = NextToken();
5479 PostChildrenInfos.push_back(Info);
5480
5481 return CXChildVisit_Recurse;
5482}
5483
5484bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5485 if (PostChildrenInfos.empty())
5486 return false;
5487 const PostChildrenInfo &Info = PostChildrenInfos.back();
5488 if (!clang_equalCursors(Info.Cursor, cursor))
5489 return false;
5490
5491 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5492 const unsigned AfterChildren = NextToken();
5493 SourceRange cursorRange = Info.CursorRange;
5494
5495 // Scan the tokens that are at the end of the cursor, but are not captured
5496 // but the child cursors.
5497 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5498
5499 // Scan the tokens that are at the beginning of the cursor, but are not
5500 // capture by the child cursors.
5501 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5502 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5503 break;
5504
5505 Cursors[I] = cursor;
5506 }
5507
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005508 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5509 // encountered the attribute cursor.
5510 if (clang_isAttribute(cursor.kind))
5511 TokIdx = Info.BeforeReachingCursorIdx;
5512
Guy Benyei11169dd2012-12-18 14:30:41 +00005513 PostChildrenInfos.pop_back();
5514 return false;
5515}
5516
5517static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5518 CXCursor parent,
5519 CXClientData client_data) {
5520 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5521}
5522
5523static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5524 CXClientData client_data) {
5525 return static_cast<AnnotateTokensWorker*>(client_data)->
5526 postVisitChildren(cursor);
5527}
5528
5529namespace {
5530
5531/// \brief Uses the macro expansions in the preprocessing record to find
5532/// and mark tokens that are macro arguments. This info is used by the
5533/// AnnotateTokensWorker.
5534class MarkMacroArgTokensVisitor {
5535 SourceManager &SM;
5536 CXToken *Tokens;
5537 unsigned NumTokens;
5538 unsigned CurIdx;
5539
5540public:
5541 MarkMacroArgTokensVisitor(SourceManager &SM,
5542 CXToken *tokens, unsigned numTokens)
5543 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5544
5545 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5546 if (cursor.kind != CXCursor_MacroExpansion)
5547 return CXChildVisit_Continue;
5548
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005549 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005550 if (macroRange.getBegin() == macroRange.getEnd())
5551 return CXChildVisit_Continue; // it's not a function macro.
5552
5553 for (; CurIdx < NumTokens; ++CurIdx) {
5554 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5555 macroRange.getBegin()))
5556 break;
5557 }
5558
5559 if (CurIdx == NumTokens)
5560 return CXChildVisit_Break;
5561
5562 for (; CurIdx < NumTokens; ++CurIdx) {
5563 SourceLocation tokLoc = getTokenLoc(CurIdx);
5564 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5565 break;
5566
5567 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5568 }
5569
5570 if (CurIdx == NumTokens)
5571 return CXChildVisit_Break;
5572
5573 return CXChildVisit_Continue;
5574 }
5575
5576private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005577 CXToken &getTok(unsigned Idx) {
5578 assert(Idx < NumTokens);
5579 return Tokens[Idx];
5580 }
5581 const CXToken &getTok(unsigned Idx) const {
5582 assert(Idx < NumTokens);
5583 return Tokens[Idx];
5584 }
5585
Guy Benyei11169dd2012-12-18 14:30:41 +00005586 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005587 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005588 }
5589
5590 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5591 // The third field is reserved and currently not used. Use it here
5592 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005593 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005594 }
5595};
5596
5597} // end anonymous namespace
5598
5599static CXChildVisitResult
5600MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5601 CXClientData client_data) {
5602 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5603 parent);
5604}
5605
5606namespace {
5607 struct clang_annotateTokens_Data {
5608 CXTranslationUnit TU;
5609 ASTUnit *CXXUnit;
5610 CXToken *Tokens;
5611 unsigned NumTokens;
5612 CXCursor *Cursors;
5613 };
5614}
5615
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005616/// \brief Used by \c annotatePreprocessorTokens.
5617/// \returns true if lexing was finished, false otherwise.
5618static bool lexNext(Lexer &Lex, Token &Tok,
5619 unsigned &NextIdx, unsigned NumTokens) {
5620 if (NextIdx >= NumTokens)
5621 return true;
5622
5623 ++NextIdx;
5624 Lex.LexFromRawLexer(Tok);
5625 if (Tok.is(tok::eof))
5626 return true;
5627
5628 return false;
5629}
5630
Guy Benyei11169dd2012-12-18 14:30:41 +00005631static void annotatePreprocessorTokens(CXTranslationUnit TU,
5632 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005633 CXCursor *Cursors,
5634 CXToken *Tokens,
5635 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005636 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005637
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005638 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005639 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5640 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005641 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005642 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005643 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005644
5645 if (BeginLocInfo.first != EndLocInfo.first)
5646 return;
5647
5648 StringRef Buffer;
5649 bool Invalid = false;
5650 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5651 if (Buffer.empty() || Invalid)
5652 return;
5653
5654 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5655 CXXUnit->getASTContext().getLangOpts(),
5656 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5657 Buffer.end());
5658 Lex.SetCommentRetentionState(true);
5659
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005660 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005661 // Lex tokens in raw mode until we hit the end of the range, to avoid
5662 // entering #includes or expanding macros.
5663 while (true) {
5664 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005665 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5666 break;
5667 unsigned TokIdx = NextIdx-1;
5668 assert(Tok.getLocation() ==
5669 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005670
5671 reprocess:
5672 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005673 // We have found a preprocessing directive. Annotate the tokens
5674 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005675 //
5676 // FIXME: Some simple tests here could identify macro definitions and
5677 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005678
5679 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005680 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5681 break;
5682
5683 MacroInfo *MI = 0;
5684 if (Tok.is(tok::raw_identifier) &&
5685 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5686 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5687 break;
5688
5689 if (Tok.is(tok::raw_identifier)) {
5690 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5691 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5692 SourceLocation MappedTokLoc =
5693 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5694 MI = getMacroInfo(II, MappedTokLoc, TU);
5695 }
5696 }
5697
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005698 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005699 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005700 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5701 finished = true;
5702 break;
5703 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005704 // If we are in a macro definition, check if the token was ever a
5705 // macro name and annotate it if that's the case.
5706 if (MI) {
5707 SourceLocation SaveLoc = Tok.getLocation();
5708 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5709 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5710 Tok.setLocation(SaveLoc);
5711 if (MacroDef)
5712 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5713 Tok.getLocation(), TU);
5714 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005715 } while (!Tok.isAtStartOfLine());
5716
5717 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5718 assert(TokIdx <= LastIdx);
5719 SourceLocation EndLoc =
5720 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5721 CXCursor Cursor =
5722 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5723
5724 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005725 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005726
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005727 if (finished)
5728 break;
5729 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005730 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005731 }
5732}
5733
5734// This gets run a separate thread to avoid stack blowout.
5735static void clang_annotateTokensImpl(void *UserData) {
5736 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5737 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5738 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5739 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5740 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5741
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005742 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005743 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5744 setThreadBackgroundPriority();
5745
5746 // Determine the region of interest, which contains all of the tokens.
5747 SourceRange RegionOfInterest;
5748 RegionOfInterest.setBegin(
5749 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5750 RegionOfInterest.setEnd(
5751 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5752 Tokens[NumTokens-1])));
5753
Guy Benyei11169dd2012-12-18 14:30:41 +00005754 // Relex the tokens within the source range to look for preprocessing
5755 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005756 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005757
5758 // If begin location points inside a macro argument, set it to the expansion
5759 // location so we can have the full context when annotating semantically.
5760 {
5761 SourceManager &SM = CXXUnit->getSourceManager();
5762 SourceLocation Loc =
5763 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5764 if (Loc.isMacroID())
5765 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5766 }
5767
Guy Benyei11169dd2012-12-18 14:30:41 +00005768 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5769 // Search and mark tokens that are macro argument expansions.
5770 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5771 Tokens, NumTokens);
5772 CursorVisitor MacroArgMarker(TU,
5773 MarkMacroArgTokensVisitorDelegate, &Visitor,
5774 /*VisitPreprocessorLast=*/true,
5775 /*VisitIncludedEntities=*/false,
5776 RegionOfInterest);
5777 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5778 }
5779
5780 // Annotate all of the source locations in the region of interest that map to
5781 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005782 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005783
5784 // FIXME: We use a ridiculous stack size here because the data-recursion
5785 // algorithm uses a large stack frame than the non-data recursive version,
5786 // and AnnotationTokensWorker currently transforms the data-recursion
5787 // algorithm back into a traditional recursion by explicitly calling
5788 // VisitChildren(). We will need to remove this explicit recursive call.
5789 W.AnnotateTokens();
5790
5791 // If we ran into any entities that involve context-sensitive keywords,
5792 // take another pass through the tokens to mark them as such.
5793 if (W.hasContextSensitiveKeywords()) {
5794 for (unsigned I = 0; I != NumTokens; ++I) {
5795 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5796 continue;
5797
5798 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5799 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005800 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005801 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5802 if (Property->getPropertyAttributesAsWritten() != 0 &&
5803 llvm::StringSwitch<bool>(II->getName())
5804 .Case("readonly", true)
5805 .Case("assign", true)
5806 .Case("unsafe_unretained", true)
5807 .Case("readwrite", true)
5808 .Case("retain", true)
5809 .Case("copy", true)
5810 .Case("nonatomic", true)
5811 .Case("atomic", true)
5812 .Case("getter", true)
5813 .Case("setter", true)
5814 .Case("strong", true)
5815 .Case("weak", true)
5816 .Default(false))
5817 Tokens[I].int_data[0] = CXToken_Keyword;
5818 }
5819 continue;
5820 }
5821
5822 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5823 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5824 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5825 if (llvm::StringSwitch<bool>(II->getName())
5826 .Case("in", true)
5827 .Case("out", true)
5828 .Case("inout", true)
5829 .Case("oneway", true)
5830 .Case("bycopy", true)
5831 .Case("byref", true)
5832 .Default(false))
5833 Tokens[I].int_data[0] = CXToken_Keyword;
5834 continue;
5835 }
5836
5837 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5838 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5839 Tokens[I].int_data[0] = CXToken_Keyword;
5840 continue;
5841 }
5842 }
5843 }
5844}
5845
5846extern "C" {
5847
5848void clang_annotateTokens(CXTranslationUnit TU,
5849 CXToken *Tokens, unsigned NumTokens,
5850 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005851 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005852 LOG_BAD_TU(TU);
5853 return;
5854 }
5855 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005856 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005857 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005858 }
5859
5860 LOG_FUNC_SECTION {
5861 *Log << TU << ' ';
5862 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5863 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5864 *Log << clang_getRange(bloc, eloc);
5865 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005866
5867 // Any token we don't specifically annotate will have a NULL cursor.
5868 CXCursor C = clang_getNullCursor();
5869 for (unsigned I = 0; I != NumTokens; ++I)
5870 Cursors[I] = C;
5871
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005872 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005873 if (!CXXUnit)
5874 return;
5875
5876 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5877
5878 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5879 llvm::CrashRecoveryContext CRC;
5880 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5881 GetSafetyThreadStackSize() * 2)) {
5882 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5883 }
5884}
5885
5886} // end: extern "C"
5887
5888//===----------------------------------------------------------------------===//
5889// Operations for querying linkage of a cursor.
5890//===----------------------------------------------------------------------===//
5891
5892extern "C" {
5893CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5894 if (!clang_isDeclaration(cursor.kind))
5895 return CXLinkage_Invalid;
5896
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005897 const Decl *D = cxcursor::getCursorDecl(cursor);
5898 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005899 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005900 case NoLinkage:
5901 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005902 case InternalLinkage: return CXLinkage_Internal;
5903 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5904 case ExternalLinkage: return CXLinkage_External;
5905 };
5906
5907 return CXLinkage_Invalid;
5908}
5909} // end: extern "C"
5910
5911//===----------------------------------------------------------------------===//
5912// Operations for querying language of a cursor.
5913//===----------------------------------------------------------------------===//
5914
5915static CXLanguageKind getDeclLanguage(const Decl *D) {
5916 if (!D)
5917 return CXLanguage_C;
5918
5919 switch (D->getKind()) {
5920 default:
5921 break;
5922 case Decl::ImplicitParam:
5923 case Decl::ObjCAtDefsField:
5924 case Decl::ObjCCategory:
5925 case Decl::ObjCCategoryImpl:
5926 case Decl::ObjCCompatibleAlias:
5927 case Decl::ObjCImplementation:
5928 case Decl::ObjCInterface:
5929 case Decl::ObjCIvar:
5930 case Decl::ObjCMethod:
5931 case Decl::ObjCProperty:
5932 case Decl::ObjCPropertyImpl:
5933 case Decl::ObjCProtocol:
5934 return CXLanguage_ObjC;
5935 case Decl::CXXConstructor:
5936 case Decl::CXXConversion:
5937 case Decl::CXXDestructor:
5938 case Decl::CXXMethod:
5939 case Decl::CXXRecord:
5940 case Decl::ClassTemplate:
5941 case Decl::ClassTemplatePartialSpecialization:
5942 case Decl::ClassTemplateSpecialization:
5943 case Decl::Friend:
5944 case Decl::FriendTemplate:
5945 case Decl::FunctionTemplate:
5946 case Decl::LinkageSpec:
5947 case Decl::Namespace:
5948 case Decl::NamespaceAlias:
5949 case Decl::NonTypeTemplateParm:
5950 case Decl::StaticAssert:
5951 case Decl::TemplateTemplateParm:
5952 case Decl::TemplateTypeParm:
5953 case Decl::UnresolvedUsingTypename:
5954 case Decl::UnresolvedUsingValue:
5955 case Decl::Using:
5956 case Decl::UsingDirective:
5957 case Decl::UsingShadow:
5958 return CXLanguage_CPlusPlus;
5959 }
5960
5961 return CXLanguage_C;
5962}
5963
5964extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005965
5966static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5967 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5968 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005969
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005970 switch (D->getAvailability()) {
5971 case AR_Available:
5972 case AR_NotYetIntroduced:
5973 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005974 return getCursorAvailabilityForDecl(
5975 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005976 return CXAvailability_Available;
5977
5978 case AR_Deprecated:
5979 return CXAvailability_Deprecated;
5980
5981 case AR_Unavailable:
5982 return CXAvailability_NotAvailable;
5983 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005984
5985 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005986}
5987
Guy Benyei11169dd2012-12-18 14:30:41 +00005988enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5989 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005990 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5991 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005992
5993 return CXAvailability_Available;
5994}
5995
5996static CXVersion convertVersion(VersionTuple In) {
5997 CXVersion Out = { -1, -1, -1 };
5998 if (In.empty())
5999 return Out;
6000
6001 Out.Major = In.getMajor();
6002
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006003 Optional<unsigned> Minor = In.getMinor();
6004 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006005 Out.Minor = *Minor;
6006 else
6007 return Out;
6008
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006009 Optional<unsigned> Subminor = In.getSubminor();
6010 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006011 Out.Subminor = *Subminor;
6012
6013 return Out;
6014}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006015
6016static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6017 int *always_deprecated,
6018 CXString *deprecated_message,
6019 int *always_unavailable,
6020 CXString *unavailable_message,
6021 CXPlatformAvailability *availability,
6022 int availability_size) {
6023 bool HadAvailAttr = false;
6024 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006025 for (auto A : D->attrs()) {
6026 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006027 HadAvailAttr = true;
6028 if (always_deprecated)
6029 *always_deprecated = 1;
6030 if (deprecated_message)
6031 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
6032 continue;
6033 }
6034
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006035 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006036 HadAvailAttr = true;
6037 if (always_unavailable)
6038 *always_unavailable = 1;
6039 if (unavailable_message) {
6040 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6041 }
6042 continue;
6043 }
6044
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006045 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006046 HadAvailAttr = true;
6047 if (N < availability_size) {
6048 availability[N].Platform
6049 = cxstring::createDup(Avail->getPlatform()->getName());
6050 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6051 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6052 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6053 availability[N].Unavailable = Avail->getUnavailable();
6054 availability[N].Message = cxstring::createDup(Avail->getMessage());
6055 }
6056 ++N;
6057 }
6058 }
6059
6060 if (!HadAvailAttr)
6061 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6062 return getCursorPlatformAvailabilityForDecl(
6063 cast<Decl>(EnumConst->getDeclContext()),
6064 always_deprecated,
6065 deprecated_message,
6066 always_unavailable,
6067 unavailable_message,
6068 availability,
6069 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006070
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006071 return N;
6072}
6073
Guy Benyei11169dd2012-12-18 14:30:41 +00006074int clang_getCursorPlatformAvailability(CXCursor cursor,
6075 int *always_deprecated,
6076 CXString *deprecated_message,
6077 int *always_unavailable,
6078 CXString *unavailable_message,
6079 CXPlatformAvailability *availability,
6080 int availability_size) {
6081 if (always_deprecated)
6082 *always_deprecated = 0;
6083 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006084 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006085 if (always_unavailable)
6086 *always_unavailable = 0;
6087 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006088 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006089
Guy Benyei11169dd2012-12-18 14:30:41 +00006090 if (!clang_isDeclaration(cursor.kind))
6091 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006092
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006093 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006094 if (!D)
6095 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006096
6097 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6098 deprecated_message,
6099 always_unavailable,
6100 unavailable_message,
6101 availability,
6102 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006103}
6104
6105void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6106 clang_disposeString(availability->Platform);
6107 clang_disposeString(availability->Message);
6108}
6109
6110CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6111 if (clang_isDeclaration(cursor.kind))
6112 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6113
6114 return CXLanguage_Invalid;
6115}
6116
6117 /// \brief If the given cursor is the "templated" declaration
6118 /// descibing a class or function template, return the class or
6119 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006120static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006121 if (!D)
6122 return 0;
6123
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006124 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006125 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6126 return FunTmpl;
6127
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006128 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006129 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6130 return ClassTmpl;
6131
6132 return D;
6133}
6134
6135CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6136 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006137 if (const Decl *D = getCursorDecl(cursor)) {
6138 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006139 if (!DC)
6140 return clang_getNullCursor();
6141
6142 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6143 getCursorTU(cursor));
6144 }
6145 }
6146
6147 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006148 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006149 return MakeCXCursor(D, getCursorTU(cursor));
6150 }
6151
6152 return clang_getNullCursor();
6153}
6154
6155CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6156 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006157 if (const Decl *D = getCursorDecl(cursor)) {
6158 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006159 if (!DC)
6160 return clang_getNullCursor();
6161
6162 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6163 getCursorTU(cursor));
6164 }
6165 }
6166
6167 // FIXME: Note that we can't easily compute the lexical context of a
6168 // statement or expression, so we return nothing.
6169 return clang_getNullCursor();
6170}
6171
6172CXFile clang_getIncludedFile(CXCursor cursor) {
6173 if (cursor.kind != CXCursor_InclusionDirective)
6174 return 0;
6175
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006176 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006177 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006178}
6179
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006180unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6181 if (C.kind != CXCursor_ObjCPropertyDecl)
6182 return CXObjCPropertyAttr_noattr;
6183
6184 unsigned Result = CXObjCPropertyAttr_noattr;
6185 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6186 ObjCPropertyDecl::PropertyAttributeKind Attr =
6187 PD->getPropertyAttributesAsWritten();
6188
6189#define SET_CXOBJCPROP_ATTR(A) \
6190 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6191 Result |= CXObjCPropertyAttr_##A
6192 SET_CXOBJCPROP_ATTR(readonly);
6193 SET_CXOBJCPROP_ATTR(getter);
6194 SET_CXOBJCPROP_ATTR(assign);
6195 SET_CXOBJCPROP_ATTR(readwrite);
6196 SET_CXOBJCPROP_ATTR(retain);
6197 SET_CXOBJCPROP_ATTR(copy);
6198 SET_CXOBJCPROP_ATTR(nonatomic);
6199 SET_CXOBJCPROP_ATTR(setter);
6200 SET_CXOBJCPROP_ATTR(atomic);
6201 SET_CXOBJCPROP_ATTR(weak);
6202 SET_CXOBJCPROP_ATTR(strong);
6203 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6204#undef SET_CXOBJCPROP_ATTR
6205
6206 return Result;
6207}
6208
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006209unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6210 if (!clang_isDeclaration(C.kind))
6211 return CXObjCDeclQualifier_None;
6212
6213 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6214 const Decl *D = getCursorDecl(C);
6215 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6216 QT = MD->getObjCDeclQualifier();
6217 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6218 QT = PD->getObjCDeclQualifier();
6219 if (QT == Decl::OBJC_TQ_None)
6220 return CXObjCDeclQualifier_None;
6221
6222 unsigned Result = CXObjCDeclQualifier_None;
6223 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6224 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6225 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6226 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6227 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6228 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6229
6230 return Result;
6231}
6232
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006233unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6234 if (!clang_isDeclaration(C.kind))
6235 return 0;
6236
6237 const Decl *D = getCursorDecl(C);
6238 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6239 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6240 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6241 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6242
6243 return 0;
6244}
6245
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006246unsigned clang_Cursor_isVariadic(CXCursor C) {
6247 if (!clang_isDeclaration(C.kind))
6248 return 0;
6249
6250 const Decl *D = getCursorDecl(C);
6251 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6252 return FD->isVariadic();
6253 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6254 return MD->isVariadic();
6255
6256 return 0;
6257}
6258
Guy Benyei11169dd2012-12-18 14:30:41 +00006259CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6260 if (!clang_isDeclaration(C.kind))
6261 return clang_getNullRange();
6262
6263 const Decl *D = getCursorDecl(C);
6264 ASTContext &Context = getCursorContext(C);
6265 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6266 if (!RC)
6267 return clang_getNullRange();
6268
6269 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6270}
6271
6272CXString clang_Cursor_getRawCommentText(CXCursor C) {
6273 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006274 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006275
6276 const Decl *D = getCursorDecl(C);
6277 ASTContext &Context = getCursorContext(C);
6278 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6279 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6280 StringRef();
6281
6282 // Don't duplicate the string because RawText points directly into source
6283 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006284 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006285}
6286
6287CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6288 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006289 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006290
6291 const Decl *D = getCursorDecl(C);
6292 const ASTContext &Context = getCursorContext(C);
6293 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6294
6295 if (RC) {
6296 StringRef BriefText = RC->getBriefText(Context);
6297
6298 // Don't duplicate the string because RawComment ensures that this memory
6299 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006300 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006301 }
6302
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006303 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006304}
6305
6306CXComment clang_Cursor_getParsedComment(CXCursor C) {
6307 if (!clang_isDeclaration(C.kind))
6308 return cxcomment::createCXComment(NULL, NULL);
6309
6310 const Decl *D = getCursorDecl(C);
6311 const ASTContext &Context = getCursorContext(C);
6312 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6313
6314 return cxcomment::createCXComment(FC, getCursorTU(C));
6315}
6316
6317CXModule clang_Cursor_getModule(CXCursor C) {
6318 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006319 if (const ImportDecl *ImportD =
6320 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006321 return ImportD->getImportedModule();
6322 }
6323
6324 return 0;
6325}
6326
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006327CXFile clang_Module_getASTFile(CXModule CXMod) {
6328 if (!CXMod)
6329 return 0;
6330 Module *Mod = static_cast<Module*>(CXMod);
6331 return const_cast<FileEntry *>(Mod->getASTFile());
6332}
6333
Guy Benyei11169dd2012-12-18 14:30:41 +00006334CXModule clang_Module_getParent(CXModule CXMod) {
6335 if (!CXMod)
6336 return 0;
6337 Module *Mod = static_cast<Module*>(CXMod);
6338 return Mod->Parent;
6339}
6340
6341CXString clang_Module_getName(CXModule CXMod) {
6342 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006343 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006344 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006345 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006346}
6347
6348CXString clang_Module_getFullName(CXModule CXMod) {
6349 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006350 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006351 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006352 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006353}
6354
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006355unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6356 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006357 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006358 LOG_BAD_TU(TU);
6359 return 0;
6360 }
6361 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006362 return 0;
6363 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006364 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6365 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6366 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006367}
6368
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006369CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6370 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006371 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006372 LOG_BAD_TU(TU);
6373 return 0;
6374 }
6375 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006376 return 0;
6377 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006378 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006379
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006380 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6381 if (Index < TopHeaders.size())
6382 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006383
6384 return 0;
6385}
6386
6387} // end: extern "C"
6388
6389//===----------------------------------------------------------------------===//
6390// C++ AST instrospection.
6391//===----------------------------------------------------------------------===//
6392
6393extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006394unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6395 if (!clang_isDeclaration(C.kind))
6396 return 0;
6397
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006398 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006399 const CXXMethodDecl *Method =
6400 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006401 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6402}
6403
Guy Benyei11169dd2012-12-18 14:30:41 +00006404unsigned clang_CXXMethod_isStatic(CXCursor C) {
6405 if (!clang_isDeclaration(C.kind))
6406 return 0;
6407
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006408 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006409 const CXXMethodDecl *Method =
6410 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006411 return (Method && Method->isStatic()) ? 1 : 0;
6412}
6413
6414unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6415 if (!clang_isDeclaration(C.kind))
6416 return 0;
6417
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006418 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006419 const CXXMethodDecl *Method =
6420 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006421 return (Method && Method->isVirtual()) ? 1 : 0;
6422}
6423} // end: extern "C"
6424
6425//===----------------------------------------------------------------------===//
6426// Attribute introspection.
6427//===----------------------------------------------------------------------===//
6428
6429extern "C" {
6430CXType clang_getIBOutletCollectionType(CXCursor C) {
6431 if (C.kind != CXCursor_IBOutletCollectionAttr)
6432 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6433
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006434 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006435 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6436
6437 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6438}
6439} // end: extern "C"
6440
6441//===----------------------------------------------------------------------===//
6442// Inspecting memory usage.
6443//===----------------------------------------------------------------------===//
6444
6445typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6446
6447static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6448 enum CXTUResourceUsageKind k,
6449 unsigned long amount) {
6450 CXTUResourceUsageEntry entry = { k, amount };
6451 entries.push_back(entry);
6452}
6453
6454extern "C" {
6455
6456const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6457 const char *str = "";
6458 switch (kind) {
6459 case CXTUResourceUsage_AST:
6460 str = "ASTContext: expressions, declarations, and types";
6461 break;
6462 case CXTUResourceUsage_Identifiers:
6463 str = "ASTContext: identifiers";
6464 break;
6465 case CXTUResourceUsage_Selectors:
6466 str = "ASTContext: selectors";
6467 break;
6468 case CXTUResourceUsage_GlobalCompletionResults:
6469 str = "Code completion: cached global results";
6470 break;
6471 case CXTUResourceUsage_SourceManagerContentCache:
6472 str = "SourceManager: content cache allocator";
6473 break;
6474 case CXTUResourceUsage_AST_SideTables:
6475 str = "ASTContext: side tables";
6476 break;
6477 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6478 str = "SourceManager: malloc'ed memory buffers";
6479 break;
6480 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6481 str = "SourceManager: mmap'ed memory buffers";
6482 break;
6483 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6484 str = "ExternalASTSource: malloc'ed memory buffers";
6485 break;
6486 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6487 str = "ExternalASTSource: mmap'ed memory buffers";
6488 break;
6489 case CXTUResourceUsage_Preprocessor:
6490 str = "Preprocessor: malloc'ed memory";
6491 break;
6492 case CXTUResourceUsage_PreprocessingRecord:
6493 str = "Preprocessor: PreprocessingRecord";
6494 break;
6495 case CXTUResourceUsage_SourceManager_DataStructures:
6496 str = "SourceManager: data structures and tables";
6497 break;
6498 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6499 str = "Preprocessor: header search tables";
6500 break;
6501 }
6502 return str;
6503}
6504
6505CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006506 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006507 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006508 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6509 return usage;
6510 }
6511
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006512 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006513 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006514 ASTContext &astContext = astUnit->getASTContext();
6515
6516 // How much memory is used by AST nodes and types?
6517 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6518 (unsigned long) astContext.getASTAllocatedMemory());
6519
6520 // How much memory is used by identifiers?
6521 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6522 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6523
6524 // How much memory is used for selectors?
6525 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6526 (unsigned long) astContext.Selectors.getTotalMemory());
6527
6528 // How much memory is used by ASTContext's side tables?
6529 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6530 (unsigned long) astContext.getSideTableAllocatedMemory());
6531
6532 // How much memory is used for caching global code completion results?
6533 unsigned long completionBytes = 0;
6534 if (GlobalCodeCompletionAllocator *completionAllocator =
6535 astUnit->getCachedCompletionAllocator().getPtr()) {
6536 completionBytes = completionAllocator->getTotalMemory();
6537 }
6538 createCXTUResourceUsageEntry(*entries,
6539 CXTUResourceUsage_GlobalCompletionResults,
6540 completionBytes);
6541
6542 // How much memory is being used by SourceManager's content cache?
6543 createCXTUResourceUsageEntry(*entries,
6544 CXTUResourceUsage_SourceManagerContentCache,
6545 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6546
6547 // How much memory is being used by the MemoryBuffer's in SourceManager?
6548 const SourceManager::MemoryBufferSizes &srcBufs =
6549 astUnit->getSourceManager().getMemoryBufferSizes();
6550
6551 createCXTUResourceUsageEntry(*entries,
6552 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6553 (unsigned long) srcBufs.malloc_bytes);
6554 createCXTUResourceUsageEntry(*entries,
6555 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6556 (unsigned long) srcBufs.mmap_bytes);
6557 createCXTUResourceUsageEntry(*entries,
6558 CXTUResourceUsage_SourceManager_DataStructures,
6559 (unsigned long) astContext.getSourceManager()
6560 .getDataStructureSizes());
6561
6562 // How much memory is being used by the ExternalASTSource?
6563 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6564 const ExternalASTSource::MemoryBufferSizes &sizes =
6565 esrc->getMemoryBufferSizes();
6566
6567 createCXTUResourceUsageEntry(*entries,
6568 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6569 (unsigned long) sizes.malloc_bytes);
6570 createCXTUResourceUsageEntry(*entries,
6571 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6572 (unsigned long) sizes.mmap_bytes);
6573 }
6574
6575 // How much memory is being used by the Preprocessor?
6576 Preprocessor &pp = astUnit->getPreprocessor();
6577 createCXTUResourceUsageEntry(*entries,
6578 CXTUResourceUsage_Preprocessor,
6579 pp.getTotalMemory());
6580
6581 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6582 createCXTUResourceUsageEntry(*entries,
6583 CXTUResourceUsage_PreprocessingRecord,
6584 pRec->getTotalMemory());
6585 }
6586
6587 createCXTUResourceUsageEntry(*entries,
6588 CXTUResourceUsage_Preprocessor_HeaderSearch,
6589 pp.getHeaderSearchInfo().getTotalMemory());
6590
6591 CXTUResourceUsage usage = { (void*) entries.get(),
6592 (unsigned) entries->size(),
6593 entries->size() ? &(*entries)[0] : 0 };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006594 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006595 return usage;
6596}
6597
6598void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6599 if (usage.data)
6600 delete (MemUsageEntries*) usage.data;
6601}
6602
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006603CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6604 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006605 skipped->count = 0;
6606 skipped->ranges = 0;
6607
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006608 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006609 LOG_BAD_TU(TU);
6610 return skipped;
6611 }
6612
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006613 if (!file)
6614 return skipped;
6615
6616 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6617 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6618 if (!ppRec)
6619 return skipped;
6620
6621 ASTContext &Ctx = astUnit->getASTContext();
6622 SourceManager &sm = Ctx.getSourceManager();
6623 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6624 FileID wantedFileID = sm.translateFile(fileEntry);
6625
6626 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6627 std::vector<SourceRange> wantedRanges;
6628 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6629 i != ei; ++i) {
6630 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6631 wantedRanges.push_back(*i);
6632 }
6633
6634 skipped->count = wantedRanges.size();
6635 skipped->ranges = new CXSourceRange[skipped->count];
6636 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6637 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6638
6639 return skipped;
6640}
6641
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006642void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6643 if (ranges) {
6644 delete[] ranges->ranges;
6645 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006646 }
6647}
6648
Guy Benyei11169dd2012-12-18 14:30:41 +00006649} // end extern "C"
6650
6651void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6652 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6653 for (unsigned I = 0; I != Usage.numEntries; ++I)
6654 fprintf(stderr, " %s: %lu\n",
6655 clang_getTUResourceUsageName(Usage.entries[I].kind),
6656 Usage.entries[I].amount);
6657
6658 clang_disposeCXTUResourceUsage(Usage);
6659}
6660
6661//===----------------------------------------------------------------------===//
6662// Misc. utility functions.
6663//===----------------------------------------------------------------------===//
6664
6665/// Default to using an 8 MB stack size on "safety" threads.
6666static unsigned SafetyStackThreadSize = 8 << 20;
6667
6668namespace clang {
6669
6670bool RunSafely(llvm::CrashRecoveryContext &CRC,
6671 void (*Fn)(void*), void *UserData,
6672 unsigned Size) {
6673 if (!Size)
6674 Size = GetSafetyThreadStackSize();
6675 if (Size)
6676 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6677 return CRC.RunSafely(Fn, UserData);
6678}
6679
6680unsigned GetSafetyThreadStackSize() {
6681 return SafetyStackThreadSize;
6682}
6683
6684void SetSafetyThreadStackSize(unsigned Value) {
6685 SafetyStackThreadSize = Value;
6686}
6687
6688}
6689
6690void clang::setThreadBackgroundPriority() {
6691 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6692 return;
6693
6694 // FIXME: Move to llvm/Support and make it cross-platform.
6695#ifdef __APPLE__
6696 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6697#endif
6698}
6699
6700void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6701 if (!Unit)
6702 return;
6703
6704 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6705 DEnd = Unit->stored_diag_end();
6706 D != DEnd; ++D) {
6707 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6708 CXString Msg = clang_formatDiagnostic(&Diag,
6709 clang_defaultDiagnosticDisplayOptions());
6710 fprintf(stderr, "%s\n", clang_getCString(Msg));
6711 clang_disposeString(Msg);
6712 }
6713#ifdef LLVM_ON_WIN32
6714 // On Windows, force a flush, since there may be multiple copies of
6715 // stderr and stdout in the file system, all with different buffers
6716 // but writing to the same device.
6717 fflush(stderr);
6718#endif
6719}
6720
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006721MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6722 SourceLocation MacroDefLoc,
6723 CXTranslationUnit TU){
6724 if (MacroDefLoc.isInvalid() || !TU)
6725 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006726 if (!II.hadMacroDefinition())
6727 return 0;
6728
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006729 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006730 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006731 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006732 if (MD) {
6733 for (MacroDirective::DefInfo
6734 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6735 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6736 return Def.getMacroInfo();
6737 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006738 }
6739
6740 return 0;
6741}
6742
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006743const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6744 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006745 if (!MacroDef || !TU)
6746 return 0;
6747 const IdentifierInfo *II = MacroDef->getName();
6748 if (!II)
6749 return 0;
6750
6751 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6752}
6753
6754MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6755 const Token &Tok,
6756 CXTranslationUnit TU) {
6757 if (!MI || !TU)
6758 return 0;
6759 if (Tok.isNot(tok::raw_identifier))
6760 return 0;
6761
6762 if (MI->getNumTokens() == 0)
6763 return 0;
6764 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6765 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006766 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006767
6768 // Check that the token is inside the definition and not its argument list.
6769 SourceManager &SM = Unit->getSourceManager();
6770 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6771 return 0;
6772 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6773 return 0;
6774
6775 Preprocessor &PP = Unit->getPreprocessor();
6776 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6777 if (!PPRec)
6778 return 0;
6779
6780 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6781 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6782 if (!II.hadMacroDefinition())
6783 return 0;
6784
6785 // Check that the identifier is not one of the macro arguments.
6786 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6787 return 0;
6788
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006789 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6790 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006791 return 0;
6792
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006793 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006794}
6795
6796MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6797 SourceLocation Loc,
6798 CXTranslationUnit TU) {
6799 if (Loc.isInvalid() || !MI || !TU)
6800 return 0;
6801
6802 if (MI->getNumTokens() == 0)
6803 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006804 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006805 Preprocessor &PP = Unit->getPreprocessor();
6806 if (!PP.getPreprocessingRecord())
6807 return 0;
6808 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6809 Token Tok;
6810 if (PP.getRawToken(Loc, Tok))
6811 return 0;
6812
6813 return checkForMacroInMacroDefinition(MI, Tok, TU);
6814}
6815
Guy Benyei11169dd2012-12-18 14:30:41 +00006816extern "C" {
6817
6818CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006819 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006820}
6821
6822} // end: extern "C"
6823
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006824Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6825 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006826 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006827 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006828 if (Unit->isMainFileAST())
6829 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006830 return *this;
6831 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006832 } else {
6833 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006834 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006835 return *this;
6836}
6837
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006838Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6839 *this << FE->getName();
6840 return *this;
6841}
6842
6843Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6844 CXString cursorName = clang_getCursorDisplayName(cursor);
6845 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6846 clang_disposeString(cursorName);
6847 return *this;
6848}
6849
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006850Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6851 CXFile File;
6852 unsigned Line, Column;
6853 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6854 CXString FileName = clang_getFileName(File);
6855 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6856 clang_disposeString(FileName);
6857 return *this;
6858}
6859
6860Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6861 CXSourceLocation BLoc = clang_getRangeStart(range);
6862 CXSourceLocation ELoc = clang_getRangeEnd(range);
6863
6864 CXFile BFile;
6865 unsigned BLine, BColumn;
6866 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6867
6868 CXFile EFile;
6869 unsigned ELine, EColumn;
6870 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6871
6872 CXString BFileName = clang_getFileName(BFile);
6873 if (BFile == EFile) {
6874 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6875 BLine, BColumn, ELine, EColumn);
6876 } else {
6877 CXString EFileName = clang_getFileName(EFile);
6878 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6879 BLine, BColumn)
6880 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6881 ELine, EColumn);
6882 clang_disposeString(EFileName);
6883 }
6884 clang_disposeString(BFileName);
6885 return *this;
6886}
6887
6888Logger &cxindex::Logger::operator<<(CXString Str) {
6889 *this << clang_getCString(Str);
6890 return *this;
6891}
6892
6893Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6894 LogOS << Fmt;
6895 return *this;
6896}
6897
6898cxindex::Logger::~Logger() {
6899 LogOS.flush();
6900
6901 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6902
6903 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6904
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006905 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006906 OS << "[libclang:" << Name << ':';
6907
6908 // FIXME: Portability.
6909#if HAVE_PTHREAD_H && __APPLE__
6910 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6911 OS << tid << ':';
6912#endif
6913
6914 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6915 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6916 OS << Msg.str() << '\n';
6917
6918 if (Trace) {
6919 llvm::sys::PrintStackTrace(stderr);
6920 OS << "--------------------------------------------------\n";
6921 }
6922}