blob: 642c1ac4a867b850a22e89441b3e73b575decff6 [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()) {
1663 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1664 E = D->bases_end(); I != E; ++I) {
1665 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1666 return true;
1667 }
1668 }
1669
1670 return VisitTagDecl(D);
1671}
1672
1673bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001674 for (const auto *I : D->attrs())
1675 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001676 return true;
1677
1678 return false;
1679}
1680
1681//===----------------------------------------------------------------------===//
1682// Data-recursive visitor methods.
1683//===----------------------------------------------------------------------===//
1684
1685namespace {
1686#define DEF_JOB(NAME, DATA, KIND)\
1687class NAME : public VisitorJob {\
1688public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001689 NAME(const DATA *d, CXCursor parent) : \
1690 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001691 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001692 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001693};
1694
1695DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1696DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1697DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1698DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1699DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1700 ExplicitTemplateArgsVisitKind)
1701DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1702DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1703DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1704#undef DEF_JOB
1705
1706class DeclVisit : public VisitorJob {
1707public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001708 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001709 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001710 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001711 static bool classof(const VisitorJob *VJ) {
1712 return VJ->getKind() == DeclVisitKind;
1713 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001714 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001715 bool isFirst() const { return data[1] ? true : false; }
1716};
1717class TypeLocVisit : public VisitorJob {
1718public:
1719 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1720 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1721 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1722
1723 static bool classof(const VisitorJob *VJ) {
1724 return VJ->getKind() == TypeLocVisitKind;
1725 }
1726
1727 TypeLoc get() const {
1728 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001729 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001730 }
1731};
1732
1733class LabelRefVisit : public VisitorJob {
1734public:
1735 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1736 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1737 labelLoc.getPtrEncoding()) {}
1738
1739 static bool classof(const VisitorJob *VJ) {
1740 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1741 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001742 const LabelDecl *get() const {
1743 return static_cast<const LabelDecl *>(data[0]);
1744 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001745 SourceLocation getLoc() const {
1746 return SourceLocation::getFromPtrEncoding(data[1]); }
1747};
1748
1749class NestedNameSpecifierLocVisit : public VisitorJob {
1750public:
1751 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1752 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1753 Qualifier.getNestedNameSpecifier(),
1754 Qualifier.getOpaqueData()) { }
1755
1756 static bool classof(const VisitorJob *VJ) {
1757 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1758 }
1759
1760 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001761 return NestedNameSpecifierLoc(
1762 const_cast<NestedNameSpecifier *>(
1763 static_cast<const NestedNameSpecifier *>(data[0])),
1764 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001765 }
1766};
1767
1768class DeclarationNameInfoVisit : public VisitorJob {
1769public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001770 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001771 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001772 static bool classof(const VisitorJob *VJ) {
1773 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1774 }
1775 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001776 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001777 switch (S->getStmtClass()) {
1778 default:
1779 llvm_unreachable("Unhandled Stmt");
1780 case clang::Stmt::MSDependentExistsStmtClass:
1781 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1782 case Stmt::CXXDependentScopeMemberExprClass:
1783 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1784 case Stmt::DependentScopeDeclRefExprClass:
1785 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1786 }
1787 }
1788};
1789class MemberRefVisit : public VisitorJob {
1790public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001791 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001792 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1793 L.getPtrEncoding()) {}
1794 static bool classof(const VisitorJob *VJ) {
1795 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1796 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001797 const FieldDecl *get() const {
1798 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001799 }
1800 SourceLocation getLoc() const {
1801 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1802 }
1803};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001804class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001805 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001806 VisitorWorkList &WL;
1807 CXCursor Parent;
1808public:
1809 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1810 : WL(wl), Parent(parent) {}
1811
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001812 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1813 void VisitBlockExpr(const BlockExpr *B);
1814 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1815 void VisitCompoundStmt(const CompoundStmt *S);
1816 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1817 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1818 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1819 void VisitCXXNewExpr(const CXXNewExpr *E);
1820 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1821 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1822 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1823 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1824 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1825 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1826 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1827 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1828 void VisitDeclRefExpr(const DeclRefExpr *D);
1829 void VisitDeclStmt(const DeclStmt *S);
1830 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1831 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1832 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1833 void VisitForStmt(const ForStmt *FS);
1834 void VisitGotoStmt(const GotoStmt *GS);
1835 void VisitIfStmt(const IfStmt *If);
1836 void VisitInitListExpr(const InitListExpr *IE);
1837 void VisitMemberExpr(const MemberExpr *M);
1838 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1839 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1840 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1841 void VisitOverloadExpr(const OverloadExpr *E);
1842 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1843 void VisitStmt(const Stmt *S);
1844 void VisitSwitchStmt(const SwitchStmt *S);
1845 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001846 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1847 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1848 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1849 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1850 void VisitVAArgExpr(const VAArgExpr *E);
1851 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1852 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1853 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1854 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001855 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1856 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001857 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001858
Guy Benyei11169dd2012-12-18 14:30:41 +00001859private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001860 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001861 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1862 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001863 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1864 void AddStmt(const Stmt *S);
1865 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001866 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001867 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001868 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001869};
1870} // end anonyous namespace
1871
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001872void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001873 // 'S' should always be non-null, since it comes from the
1874 // statement we are visiting.
1875 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1876}
1877
1878void
1879EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1880 if (Qualifier)
1881 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1882}
1883
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001884void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001885 if (S)
1886 WL.push_back(StmtVisit(S, Parent));
1887}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001888void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001889 if (D)
1890 WL.push_back(DeclVisit(D, Parent, isFirst));
1891}
1892void EnqueueVisitor::
1893 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1894 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001895 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001896}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001897void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001898 if (D)
1899 WL.push_back(MemberRefVisit(D, L, Parent));
1900}
1901void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1902 if (TI)
1903 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1904 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001905void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001906 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001907 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001908 AddStmt(*Child);
1909 }
1910 if (size == WL.size())
1911 return;
1912 // Now reverse the entries we just added. This will match the DFS
1913 // ordering performed by the worklist.
1914 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1915 std::reverse(I, E);
1916}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001917namespace {
1918class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1919 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001920 /// \brief Process clauses with list of variables.
1921 template <typename T>
1922 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001923public:
1924 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1925#define OPENMP_CLAUSE(Name, Class) \
1926 void Visit##Class(const Class *C);
1927#include "clang/Basic/OpenMPKinds.def"
1928};
1929
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001930void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1931 Visitor->AddStmt(C->getCondition());
1932}
1933
Alexey Bataev568a8332014-03-06 06:15:19 +00001934void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1935 Visitor->AddStmt(C->getNumThreads());
1936}
1937
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001938void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001939
1940template<typename T>
1941void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
1942 for (typename T::varlist_const_iterator I = Node->varlist_begin(),
1943 E = Node->varlist_end();
1944 I != E; ++I)
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001945 Visitor->AddStmt(*I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001946}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001947
1948void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001949 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001950}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001951void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1952 const OMPFirstprivateClause *C) {
1953 VisitOMPClauseList(C);
1954}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001955void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001956 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001957}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001958}
Alexey Bataev756c1962013-09-24 03:17:45 +00001959
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001960void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1961 unsigned size = WL.size();
1962 OMPClauseEnqueue Visitor(this);
1963 Visitor.Visit(S);
1964 if (size == WL.size())
1965 return;
1966 // Now reverse the entries we just added. This will match the DFS
1967 // ordering performed by the worklist.
1968 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1969 std::reverse(I, E);
1970}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001971void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001972 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1973}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001974void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001975 AddDecl(B->getBlockDecl());
1976}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001977void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001978 EnqueueChildren(E);
1979 AddTypeLoc(E->getTypeSourceInfo());
1980}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001981void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1982 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001983 E = S->body_rend(); I != E; ++I) {
1984 AddStmt(*I);
1985 }
1986}
1987void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001988VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001989 AddStmt(S->getSubStmt());
1990 AddDeclarationNameInfo(S);
1991 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1992 AddNestedNameSpecifierLoc(QualifierLoc);
1993}
1994
1995void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001996VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001997 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1998 AddDeclarationNameInfo(E);
1999 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2000 AddNestedNameSpecifierLoc(QualifierLoc);
2001 if (!E->isImplicitAccess())
2002 AddStmt(E->getBase());
2003}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002004void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002005 // Enqueue the initializer , if any.
2006 AddStmt(E->getInitializer());
2007 // Enqueue the array size, if any.
2008 AddStmt(E->getArraySize());
2009 // Enqueue the allocated type.
2010 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2011 // Enqueue the placement arguments.
2012 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2013 AddStmt(E->getPlacementArg(I-1));
2014}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002015void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002016 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2017 AddStmt(CE->getArg(I-1));
2018 AddStmt(CE->getCallee());
2019 AddStmt(CE->getArg(0));
2020}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002021void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2022 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002023 // Visit the name of the type being destroyed.
2024 AddTypeLoc(E->getDestroyedTypeInfo());
2025 // Visit the scope type that looks disturbingly like the nested-name-specifier
2026 // but isn't.
2027 AddTypeLoc(E->getScopeTypeInfo());
2028 // Visit the nested-name-specifier.
2029 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2030 AddNestedNameSpecifierLoc(QualifierLoc);
2031 // Visit base expression.
2032 AddStmt(E->getBase());
2033}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002034void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2035 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002036 AddTypeLoc(E->getTypeSourceInfo());
2037}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002038void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2039 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002040 EnqueueChildren(E);
2041 AddTypeLoc(E->getTypeSourceInfo());
2042}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002043void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002044 EnqueueChildren(E);
2045 if (E->isTypeOperand())
2046 AddTypeLoc(E->getTypeOperandSourceInfo());
2047}
2048
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002049void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2050 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002051 EnqueueChildren(E);
2052 AddTypeLoc(E->getTypeSourceInfo());
2053}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002054void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002055 EnqueueChildren(E);
2056 if (E->isTypeOperand())
2057 AddTypeLoc(E->getTypeOperandSourceInfo());
2058}
2059
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002060void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002061 EnqueueChildren(S);
2062 AddDecl(S->getExceptionDecl());
2063}
2064
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002065void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002066 if (DR->hasExplicitTemplateArgs()) {
2067 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2068 }
2069 WL.push_back(DeclRefExprParts(DR, Parent));
2070}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002071void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2072 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002073 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2074 AddDeclarationNameInfo(E);
2075 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2076}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002077void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002078 unsigned size = WL.size();
2079 bool isFirst = true;
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002080 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00002081 D != DEnd; ++D) {
2082 AddDecl(*D, isFirst);
2083 isFirst = false;
2084 }
2085 if (size == WL.size())
2086 return;
2087 // Now reverse the entries we just added. This will match the DFS
2088 // ordering performed by the worklist.
2089 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2090 std::reverse(I, E);
2091}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002092void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002093 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002094 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002095 D = E->designators_rbegin(), DEnd = E->designators_rend();
2096 D != DEnd; ++D) {
2097 if (D->isFieldDesignator()) {
2098 if (FieldDecl *Field = D->getField())
2099 AddMemberRef(Field, D->getFieldLoc());
2100 continue;
2101 }
2102 if (D->isArrayDesignator()) {
2103 AddStmt(E->getArrayIndex(*D));
2104 continue;
2105 }
2106 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2107 AddStmt(E->getArrayRangeEnd(*D));
2108 AddStmt(E->getArrayRangeStart(*D));
2109 }
2110}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002111void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002112 EnqueueChildren(E);
2113 AddTypeLoc(E->getTypeInfoAsWritten());
2114}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002115void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002116 AddStmt(FS->getBody());
2117 AddStmt(FS->getInc());
2118 AddStmt(FS->getCond());
2119 AddDecl(FS->getConditionVariable());
2120 AddStmt(FS->getInit());
2121}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002122void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002123 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2124}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002125void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002126 AddStmt(If->getElse());
2127 AddStmt(If->getThen());
2128 AddStmt(If->getCond());
2129 AddDecl(If->getConditionVariable());
2130}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002131void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002132 // We care about the syntactic form of the initializer list, only.
2133 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2134 IE = Syntactic;
2135 EnqueueChildren(IE);
2136}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002137void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002138 WL.push_back(MemberExprParts(M, Parent));
2139
2140 // If the base of the member access expression is an implicit 'this', don't
2141 // visit it.
2142 // FIXME: If we ever want to show these implicit accesses, this will be
2143 // unfortunate. However, clang_getCursor() relies on this behavior.
2144 if (!M->isImplicitAccess())
2145 AddStmt(M->getBase());
2146}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002147void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002148 AddTypeLoc(E->getEncodedTypeSourceInfo());
2149}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002150void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002151 EnqueueChildren(M);
2152 AddTypeLoc(M->getClassReceiverTypeInfo());
2153}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002154void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002155 // Visit the components of the offsetof expression.
2156 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2157 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2158 const OffsetOfNode &Node = E->getComponent(I-1);
2159 switch (Node.getKind()) {
2160 case OffsetOfNode::Array:
2161 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2162 break;
2163 case OffsetOfNode::Field:
2164 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2165 break;
2166 case OffsetOfNode::Identifier:
2167 case OffsetOfNode::Base:
2168 continue;
2169 }
2170 }
2171 // Visit the type into which we're computing the offset.
2172 AddTypeLoc(E->getTypeSourceInfo());
2173}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002174void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002175 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2176 WL.push_back(OverloadExprParts(E, Parent));
2177}
2178void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002179 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002180 EnqueueChildren(E);
2181 if (E->isArgumentType())
2182 AddTypeLoc(E->getArgumentTypeInfo());
2183}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002184void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002185 EnqueueChildren(S);
2186}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002187void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002188 AddStmt(S->getBody());
2189 AddStmt(S->getCond());
2190 AddDecl(S->getConditionVariable());
2191}
2192
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002193void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002194 AddStmt(W->getBody());
2195 AddStmt(W->getCond());
2196 AddDecl(W->getConditionVariable());
2197}
2198
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002199void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002200 for (unsigned I = E->getNumArgs(); I > 0; --I)
2201 AddTypeLoc(E->getArg(I-1));
2202}
2203
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002204void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002205 AddTypeLoc(E->getQueriedTypeSourceInfo());
2206}
2207
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002208void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002209 EnqueueChildren(E);
2210}
2211
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002212void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002213 VisitOverloadExpr(U);
2214 if (!U->isImplicitAccess())
2215 AddStmt(U->getBase());
2216}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002218 AddStmt(E->getSubExpr());
2219 AddTypeLoc(E->getWrittenTypeInfo());
2220}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002221void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002222 WL.push_back(SizeOfPackExprParts(E, Parent));
2223}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002224void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002225 // If the opaque value has a source expression, just transparently
2226 // visit that. This is useful for (e.g.) pseudo-object expressions.
2227 if (Expr *SourceExpr = E->getSourceExpr())
2228 return Visit(SourceExpr);
2229}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002230void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002231 AddStmt(E->getBody());
2232 WL.push_back(LambdaExprParts(E, Parent));
2233}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002234void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002235 // Treat the expression like its syntactic form.
2236 Visit(E->getSyntacticForm());
2237}
2238
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002239void EnqueueVisitor::VisitOMPExecutableDirective(
2240 const OMPExecutableDirective *D) {
2241 EnqueueChildren(D);
2242 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2243 E = D->clauses().end();
2244 I != E; ++I)
2245 EnqueueChildren(*I);
2246}
2247
2248void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2249 VisitOMPExecutableDirective(D);
2250}
2251
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002252void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2253 VisitOMPExecutableDirective(D);
2254}
2255
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002256void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002257 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2258}
2259
2260bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2261 if (RegionOfInterest.isValid()) {
2262 SourceRange Range = getRawCursorExtent(C);
2263 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2264 return false;
2265 }
2266 return true;
2267}
2268
2269bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2270 while (!WL.empty()) {
2271 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002272 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002273
2274 // Set the Parent field, then back to its old value once we're done.
2275 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2276
2277 switch (LI.getKind()) {
2278 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002279 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002280 if (!D)
2281 continue;
2282
2283 // For now, perform default visitation for Decls.
2284 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2285 cast<DeclVisit>(&LI)->isFirst())))
2286 return true;
2287
2288 continue;
2289 }
2290 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2291 const ASTTemplateArgumentListInfo *ArgList =
2292 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2293 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2294 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2295 Arg != ArgEnd; ++Arg) {
2296 if (VisitTemplateArgumentLoc(*Arg))
2297 return true;
2298 }
2299 continue;
2300 }
2301 case VisitorJob::TypeLocVisitKind: {
2302 // Perform default visitation for TypeLocs.
2303 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2304 return true;
2305 continue;
2306 }
2307 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002308 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002309 if (LabelStmt *stmt = LS->getStmt()) {
2310 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2311 TU))) {
2312 return true;
2313 }
2314 }
2315 continue;
2316 }
2317
2318 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2319 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2320 if (VisitNestedNameSpecifierLoc(V->get()))
2321 return true;
2322 continue;
2323 }
2324
2325 case VisitorJob::DeclarationNameInfoVisitKind: {
2326 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2327 ->get()))
2328 return true;
2329 continue;
2330 }
2331 case VisitorJob::MemberRefVisitKind: {
2332 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2333 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2334 return true;
2335 continue;
2336 }
2337 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002338 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002339 if (!S)
2340 continue;
2341
2342 // Update the current cursor.
2343 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2344 if (!IsInRegionOfInterest(Cursor))
2345 continue;
2346 switch (Visitor(Cursor, Parent, ClientData)) {
2347 case CXChildVisit_Break: return true;
2348 case CXChildVisit_Continue: break;
2349 case CXChildVisit_Recurse:
2350 if (PostChildrenVisitor)
2351 WL.push_back(PostChildrenVisit(0, Cursor));
2352 EnqueueWorkList(WL, S);
2353 break;
2354 }
2355 continue;
2356 }
2357 case VisitorJob::MemberExprPartsKind: {
2358 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002359 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002360
2361 // Visit the nested-name-specifier
2362 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2363 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2364 return true;
2365
2366 // Visit the declaration name.
2367 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2368 return true;
2369
2370 // Visit the explicitly-specified template arguments, if any.
2371 if (M->hasExplicitTemplateArgs()) {
2372 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2373 *ArgEnd = Arg + M->getNumTemplateArgs();
2374 Arg != ArgEnd; ++Arg) {
2375 if (VisitTemplateArgumentLoc(*Arg))
2376 return true;
2377 }
2378 }
2379 continue;
2380 }
2381 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002382 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002383 // Visit nested-name-specifier, if present.
2384 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2385 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2386 return true;
2387 // Visit declaration name.
2388 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2389 return true;
2390 continue;
2391 }
2392 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002393 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002394 // Visit the nested-name-specifier.
2395 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2396 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2397 return true;
2398 // Visit the declaration name.
2399 if (VisitDeclarationNameInfo(O->getNameInfo()))
2400 return true;
2401 // Visit the overloaded declaration reference.
2402 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2403 return true;
2404 continue;
2405 }
2406 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002407 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002408 NamedDecl *Pack = E->getPack();
2409 if (isa<TemplateTypeParmDecl>(Pack)) {
2410 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2411 E->getPackLoc(), TU)))
2412 return true;
2413
2414 continue;
2415 }
2416
2417 if (isa<TemplateTemplateParmDecl>(Pack)) {
2418 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2419 E->getPackLoc(), TU)))
2420 return true;
2421
2422 continue;
2423 }
2424
2425 // Non-type template parameter packs and function parameter packs are
2426 // treated like DeclRefExpr cursors.
2427 continue;
2428 }
2429
2430 case VisitorJob::LambdaExprPartsKind: {
2431 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002432 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002433 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2434 CEnd = E->explicit_capture_end();
2435 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002436 // FIXME: Lambda init-captures.
2437 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002438 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002439
Guy Benyei11169dd2012-12-18 14:30:41 +00002440 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2441 C->getLocation(),
2442 TU)))
2443 return true;
2444 }
2445
2446 // Visit parameters and return type, if present.
2447 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2448 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2449 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2450 // Visit the whole type.
2451 if (Visit(TL))
2452 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002453 } else if (FunctionProtoTypeLoc Proto =
2454 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002455 if (E->hasExplicitParameters()) {
2456 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002457 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2458 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002459 return true;
2460 } else {
2461 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002462 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002463 return true;
2464 }
2465 }
2466 }
2467 break;
2468 }
2469
2470 case VisitorJob::PostChildrenVisitKind:
2471 if (PostChildrenVisitor(Parent, ClientData))
2472 return true;
2473 break;
2474 }
2475 }
2476 return false;
2477}
2478
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002479bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002480 VisitorWorkList *WL = 0;
2481 if (!WorkListFreeList.empty()) {
2482 WL = WorkListFreeList.back();
2483 WL->clear();
2484 WorkListFreeList.pop_back();
2485 }
2486 else {
2487 WL = new VisitorWorkList();
2488 WorkListCache.push_back(WL);
2489 }
2490 EnqueueWorkList(*WL, S);
2491 bool result = RunVisitorWorkList(*WL);
2492 WorkListFreeList.push_back(WL);
2493 return result;
2494}
2495
2496namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002497typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002498RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2499 const DeclarationNameInfo &NI,
2500 const SourceRange &QLoc,
2501 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2502 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2503 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2504 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2505
2506 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2507
2508 RefNamePieces Pieces;
2509
2510 if (WantQualifier && QLoc.isValid())
2511 Pieces.push_back(QLoc);
2512
2513 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2514 Pieces.push_back(NI.getLoc());
2515
2516 if (WantTemplateArgs && TemplateArgs)
2517 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2518 TemplateArgs->RAngleLoc));
2519
2520 if (Kind == DeclarationName::CXXOperatorName) {
2521 Pieces.push_back(SourceLocation::getFromRawEncoding(
2522 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2523 Pieces.push_back(SourceLocation::getFromRawEncoding(
2524 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2525 }
2526
2527 if (WantSinglePiece) {
2528 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2529 Pieces.clear();
2530 Pieces.push_back(R);
2531 }
2532
2533 return Pieces;
2534}
2535}
2536
2537//===----------------------------------------------------------------------===//
2538// Misc. API hooks.
2539//===----------------------------------------------------------------------===//
2540
2541static llvm::sys::Mutex EnableMultithreadingMutex;
2542static bool EnabledMultithreading;
2543
Chad Rosier05c71aa2013-03-27 18:28:23 +00002544static void fatal_error_handler(void *user_data, const std::string& reason,
2545 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002546 // Write the result out to stderr avoiding errs() because raw_ostreams can
2547 // call report_fatal_error.
2548 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2549 ::abort();
2550}
2551
2552extern "C" {
2553CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2554 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002555 // We use crash recovery to make some of our APIs more reliable, implicitly
2556 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002557 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2558 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002559
2560 // Enable support for multithreading in LLVM.
2561 {
2562 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2563 if (!EnabledMultithreading) {
2564 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2565 llvm::llvm_start_multithreaded();
2566 EnabledMultithreading = true;
2567 }
2568 }
2569
2570 CIndexer *CIdxr = new CIndexer();
2571 if (excludeDeclarationsFromPCH)
2572 CIdxr->setOnlyLocalDecls();
2573 if (displayDiagnostics)
2574 CIdxr->setDisplayDiagnostics();
2575
2576 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2577 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2578 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2579 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2580 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2581 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2582
2583 return CIdxr;
2584}
2585
2586void clang_disposeIndex(CXIndex CIdx) {
2587 if (CIdx)
2588 delete static_cast<CIndexer *>(CIdx);
2589}
2590
2591void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2592 if (CIdx)
2593 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2594}
2595
2596unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2597 if (CIdx)
2598 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2599 return 0;
2600}
2601
2602void clang_toggleCrashRecovery(unsigned isEnabled) {
2603 if (isEnabled)
2604 llvm::CrashRecoveryContext::Enable();
2605 else
2606 llvm::CrashRecoveryContext::Disable();
2607}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002608
Guy Benyei11169dd2012-12-18 14:30:41 +00002609CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2610 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002611 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002612 enum CXErrorCode Result =
2613 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002614 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002615 assert((TU && Result == CXError_Success) ||
2616 (!TU && Result != CXError_Success));
2617 return TU;
2618}
2619
2620enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2621 const char *ast_filename,
2622 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002623 if (out_TU)
2624 *out_TU = NULL;
2625
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002626 if (!CIdx || !ast_filename || !out_TU)
2627 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002628
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002629 LOG_FUNC_SECTION {
2630 *Log << ast_filename;
2631 }
2632
Guy Benyei11169dd2012-12-18 14:30:41 +00002633 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2634 FileSystemOptions FileSystemOpts;
2635
2636 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002637 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002638 CXXIdx->getOnlyLocalDecls(), None,
2639 /*CaptureDiagnostics=*/true,
2640 /*AllowPCHWithCompilerErrors=*/true,
2641 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002642 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2643 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002644}
2645
2646unsigned clang_defaultEditingTranslationUnitOptions() {
2647 return CXTranslationUnit_PrecompiledPreamble |
2648 CXTranslationUnit_CacheCompletionResults;
2649}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002650
Guy Benyei11169dd2012-12-18 14:30:41 +00002651CXTranslationUnit
2652clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2653 const char *source_filename,
2654 int num_command_line_args,
2655 const char * const *command_line_args,
2656 unsigned num_unsaved_files,
2657 struct CXUnsavedFile *unsaved_files) {
2658 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2659 return clang_parseTranslationUnit(CIdx, source_filename,
2660 command_line_args, num_command_line_args,
2661 unsaved_files, num_unsaved_files,
2662 Options);
2663}
2664
2665struct ParseTranslationUnitInfo {
2666 CXIndex CIdx;
2667 const char *source_filename;
2668 const char *const *command_line_args;
2669 int num_command_line_args;
2670 struct CXUnsavedFile *unsaved_files;
2671 unsigned num_unsaved_files;
2672 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002673 CXTranslationUnit *out_TU;
2674 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002675};
2676static void clang_parseTranslationUnit_Impl(void *UserData) {
2677 ParseTranslationUnitInfo *PTUI =
2678 static_cast<ParseTranslationUnitInfo*>(UserData);
2679 CXIndex CIdx = PTUI->CIdx;
2680 const char *source_filename = PTUI->source_filename;
2681 const char * const *command_line_args = PTUI->command_line_args;
2682 int num_command_line_args = PTUI->num_command_line_args;
2683 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2684 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2685 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002686 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002687
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002688 // Set up the initial return values.
2689 if (out_TU)
2690 *out_TU = NULL;
2691 PTUI->result = CXError_Failure;
2692
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002693 // Check arguments.
2694 if (!CIdx || !out_TU ||
2695 (unsaved_files == NULL && num_unsaved_files != 0)) {
2696 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002697 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002698 }
2699
Guy Benyei11169dd2012-12-18 14:30:41 +00002700 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2701
2702 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2703 setThreadBackgroundPriority();
2704
2705 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2706 // FIXME: Add a flag for modules.
2707 TranslationUnitKind TUKind
2708 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002709 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002710 = options & CXTranslationUnit_CacheCompletionResults;
2711 bool IncludeBriefCommentsInCodeCompletion
2712 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2713 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2714 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2715
2716 // Configure the diagnostics.
2717 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002718 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002719
2720 // Recover resources if we crash before exiting this function.
2721 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2722 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2723 DiagCleanup(Diags.getPtr());
2724
Ahmed Charlesb8984322014-03-07 20:03:18 +00002725 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2726 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002727
2728 // Recover resources if we crash before exiting this function.
2729 llvm::CrashRecoveryContextCleanupRegistrar<
2730 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2731
2732 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2733 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2734 const llvm::MemoryBuffer *Buffer
2735 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2736 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2737 Buffer));
2738 }
2739
Ahmed Charlesb8984322014-03-07 20:03:18 +00002740 std::unique_ptr<std::vector<const char *>> Args(
2741 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002742
2743 // Recover resources if we crash before exiting this method.
2744 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2745 ArgsCleanup(Args.get());
2746
2747 // Since the Clang C library is primarily used by batch tools dealing with
2748 // (often very broken) source code, where spell-checking can have a
2749 // significant negative impact on performance (particularly when
2750 // precompiled headers are involved), we disable it by default.
2751 // Only do this if we haven't found a spell-checking-related argument.
2752 bool FoundSpellCheckingArgument = false;
2753 for (int I = 0; I != num_command_line_args; ++I) {
2754 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2755 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2756 FoundSpellCheckingArgument = true;
2757 break;
2758 }
2759 }
2760 if (!FoundSpellCheckingArgument)
2761 Args->push_back("-fno-spell-checking");
2762
2763 Args->insert(Args->end(), command_line_args,
2764 command_line_args + num_command_line_args);
2765
2766 // The 'source_filename' argument is optional. If the caller does not
2767 // specify it then it is assumed that the source file is specified
2768 // in the actual argument list.
2769 // Put the source file after command_line_args otherwise if '-x' flag is
2770 // present it will be unused.
2771 if (source_filename)
2772 Args->push_back(source_filename);
2773
2774 // Do we need the detailed preprocessing record?
2775 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2776 Args->push_back("-Xclang");
2777 Args->push_back("-detailed-preprocessing-record");
2778 }
2779
2780 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002781 std::unique_ptr<ASTUnit> ErrUnit;
2782 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002783 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002784 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2785 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2786 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2787 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2788 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2789 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002790
2791 if (NumErrors != Diags->getClient()->getNumErrors()) {
2792 // Make sure to check that 'Unit' is non-NULL.
2793 if (CXXIdx->getDisplayDiagnostics())
2794 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2795 }
2796
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002797 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2798 PTUI->result = CXError_ASTReadError;
2799 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002800 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002801 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2802 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002803}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002804
2805CXTranslationUnit
2806clang_parseTranslationUnit(CXIndex CIdx,
2807 const char *source_filename,
2808 const char *const *command_line_args,
2809 int num_command_line_args,
2810 struct CXUnsavedFile *unsaved_files,
2811 unsigned num_unsaved_files,
2812 unsigned options) {
2813 CXTranslationUnit TU;
2814 enum CXErrorCode Result = clang_parseTranslationUnit2(
2815 CIdx, source_filename, command_line_args, num_command_line_args,
2816 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002817 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002818 assert((TU && Result == CXError_Success) ||
2819 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002820 return TU;
2821}
2822
2823enum CXErrorCode clang_parseTranslationUnit2(
2824 CXIndex CIdx,
2825 const char *source_filename,
2826 const char *const *command_line_args,
2827 int num_command_line_args,
2828 struct CXUnsavedFile *unsaved_files,
2829 unsigned num_unsaved_files,
2830 unsigned options,
2831 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002832 LOG_FUNC_SECTION {
2833 *Log << source_filename << ": ";
2834 for (int i = 0; i != num_command_line_args; ++i)
2835 *Log << command_line_args[i] << " ";
2836 }
2837
Guy Benyei11169dd2012-12-18 14:30:41 +00002838 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2839 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002840 num_unsaved_files, options, out_TU,
2841 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002842 llvm::CrashRecoveryContext CRC;
2843
2844 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2845 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2846 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2847 fprintf(stderr, " 'command_line_args' : [");
2848 for (int i = 0; i != num_command_line_args; ++i) {
2849 if (i)
2850 fprintf(stderr, ", ");
2851 fprintf(stderr, "'%s'", command_line_args[i]);
2852 }
2853 fprintf(stderr, "],\n");
2854 fprintf(stderr, " 'unsaved_files' : [");
2855 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2856 if (i)
2857 fprintf(stderr, ", ");
2858 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2859 unsaved_files[i].Length);
2860 }
2861 fprintf(stderr, "],\n");
2862 fprintf(stderr, " 'options' : %d,\n", options);
2863 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002864
2865 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002866 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002867 if (CXTranslationUnit *TU = PTUI.out_TU)
2868 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002869 }
2870
2871 return PTUI.result;
2872}
2873
2874unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2875 return CXSaveTranslationUnit_None;
2876}
2877
2878namespace {
2879
2880struct SaveTranslationUnitInfo {
2881 CXTranslationUnit TU;
2882 const char *FileName;
2883 unsigned options;
2884 CXSaveError result;
2885};
2886
2887}
2888
2889static void clang_saveTranslationUnit_Impl(void *UserData) {
2890 SaveTranslationUnitInfo *STUI =
2891 static_cast<SaveTranslationUnitInfo*>(UserData);
2892
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002893 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002894 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2895 setThreadBackgroundPriority();
2896
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002897 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002898 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2899}
2900
2901int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2902 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002903 LOG_FUNC_SECTION {
2904 *Log << TU << ' ' << FileName;
2905 }
2906
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002907 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002908 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002909 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002910 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002911
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002912 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002913 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2914 if (!CXXUnit->hasSema())
2915 return CXSaveError_InvalidTU;
2916
2917 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2918
2919 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2920 getenv("LIBCLANG_NOTHREADS")) {
2921 clang_saveTranslationUnit_Impl(&STUI);
2922
2923 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2924 PrintLibclangResourceUsage(TU);
2925
2926 return STUI.result;
2927 }
2928
2929 // We have an AST that has invalid nodes due to compiler errors.
2930 // Use a crash recovery thread for protection.
2931
2932 llvm::CrashRecoveryContext CRC;
2933
2934 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2935 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2936 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2937 fprintf(stderr, " 'options' : %d,\n", options);
2938 fprintf(stderr, "}\n");
2939
2940 return CXSaveError_Unknown;
2941
2942 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2943 PrintLibclangResourceUsage(TU);
2944 }
2945
2946 return STUI.result;
2947}
2948
2949void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2950 if (CTUnit) {
2951 // If the translation unit has been marked as unsafe to free, just discard
2952 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002953 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2954 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002955 return;
2956
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002957 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002958 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002959 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2960 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002961 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002962 delete CTUnit;
2963 }
2964}
2965
2966unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2967 return CXReparse_None;
2968}
2969
2970struct ReparseTranslationUnitInfo {
2971 CXTranslationUnit TU;
2972 unsigned num_unsaved_files;
2973 struct CXUnsavedFile *unsaved_files;
2974 unsigned options;
2975 int result;
2976};
2977
2978static void clang_reparseTranslationUnit_Impl(void *UserData) {
2979 ReparseTranslationUnitInfo *RTUI =
2980 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002981 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002982
Guy Benyei11169dd2012-12-18 14:30:41 +00002983 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002984 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2985 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2986 unsigned options = RTUI->options;
2987 (void) options;
2988
2989 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002990 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002991 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002992 RTUI->result = CXError_InvalidArguments;
2993 return;
2994 }
2995 if (unsaved_files == NULL && num_unsaved_files != 0) {
2996 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00002997 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002998 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002999
3000 // Reset the associated diagnostics.
3001 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3002 TU->Diagnostics = 0;
3003
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003004 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003005 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3006 setThreadBackgroundPriority();
3007
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003008 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003009 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003010
3011 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3012 new std::vector<ASTUnit::RemappedFile>());
3013
Guy Benyei11169dd2012-12-18 14:30:41 +00003014 // Recover resources if we crash before exiting this function.
3015 llvm::CrashRecoveryContextCleanupRegistrar<
3016 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3017
3018 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3019 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3020 const llvm::MemoryBuffer *Buffer
3021 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3022 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3023 Buffer));
3024 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003025
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003026 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003027 RTUI->result = CXError_Success;
3028 else if (isASTReadError(CXXUnit))
3029 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003030}
3031
3032int clang_reparseTranslationUnit(CXTranslationUnit TU,
3033 unsigned num_unsaved_files,
3034 struct CXUnsavedFile *unsaved_files,
3035 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003036 LOG_FUNC_SECTION {
3037 *Log << TU;
3038 }
3039
Guy Benyei11169dd2012-12-18 14:30:41 +00003040 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003041 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003042
3043 if (getenv("LIBCLANG_NOTHREADS")) {
3044 clang_reparseTranslationUnit_Impl(&RTUI);
3045 return RTUI.result;
3046 }
3047
3048 llvm::CrashRecoveryContext CRC;
3049
3050 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3051 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003052 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003053 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003054 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3055 PrintLibclangResourceUsage(TU);
3056
3057 return RTUI.result;
3058}
3059
3060
3061CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003062 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003063 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003064 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003065 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003066
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003067 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003068 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003069}
3070
3071CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003072 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003073 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003074 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003075 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003076
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003077 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003078 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3079}
3080
3081} // end: extern "C"
3082
3083//===----------------------------------------------------------------------===//
3084// CXFile Operations.
3085//===----------------------------------------------------------------------===//
3086
3087extern "C" {
3088CXString clang_getFileName(CXFile SFile) {
3089 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003090 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003091
3092 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003093 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003094}
3095
3096time_t clang_getFileTime(CXFile SFile) {
3097 if (!SFile)
3098 return 0;
3099
3100 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3101 return FEnt->getModificationTime();
3102}
3103
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003104CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003105 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003106 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003107 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003108 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003109
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003110 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003111
3112 FileManager &FMgr = CXXUnit->getFileManager();
3113 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3114}
3115
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003116unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3117 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003118 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003119 LOG_BAD_TU(TU);
3120 return 0;
3121 }
3122
3123 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003124 return 0;
3125
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003126 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003127 FileEntry *FEnt = static_cast<FileEntry *>(file);
3128 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3129 .isFileMultipleIncludeGuarded(FEnt);
3130}
3131
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003132int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3133 if (!file || !outID)
3134 return 1;
3135
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003136 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003137 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3138 outID->data[0] = ID.getDevice();
3139 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003140 outID->data[2] = FEnt->getModificationTime();
3141 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003142}
3143
Guy Benyei11169dd2012-12-18 14:30:41 +00003144} // end: extern "C"
3145
3146//===----------------------------------------------------------------------===//
3147// CXCursor Operations.
3148//===----------------------------------------------------------------------===//
3149
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003150static const Decl *getDeclFromExpr(const Stmt *E) {
3151 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003152 return getDeclFromExpr(CE->getSubExpr());
3153
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003154 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003155 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003156 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003157 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003158 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003159 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003160 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003161 if (PRE->isExplicitProperty())
3162 return PRE->getExplicitProperty();
3163 // It could be messaging both getter and setter as in:
3164 // ++myobj.myprop;
3165 // in which case prefer to associate the setter since it is less obvious
3166 // from inspecting the source that the setter is going to get called.
3167 if (PRE->isMessagingSetter())
3168 return PRE->getImplicitPropertySetter();
3169 return PRE->getImplicitPropertyGetter();
3170 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003171 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003172 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003173 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003174 if (Expr *Src = OVE->getSourceExpr())
3175 return getDeclFromExpr(Src);
3176
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003177 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003178 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003179 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003180 if (!CE->isElidable())
3181 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003182 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003183 return OME->getMethodDecl();
3184
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003185 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003186 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003187 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003188 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3189 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003190 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003191 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3192 isa<ParmVarDecl>(SizeOfPack->getPack()))
3193 return SizeOfPack->getPack();
3194
3195 return 0;
3196}
3197
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003198static SourceLocation getLocationFromExpr(const Expr *E) {
3199 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003200 return getLocationFromExpr(CE->getSubExpr());
3201
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003202 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003203 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003204 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003205 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003206 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003207 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003208 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003209 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003210 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003211 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003212 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003213 return PropRef->getLocation();
3214
3215 return E->getLocStart();
3216}
3217
3218extern "C" {
3219
3220unsigned clang_visitChildren(CXCursor parent,
3221 CXCursorVisitor visitor,
3222 CXClientData client_data) {
3223 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3224 /*VisitPreprocessorLast=*/false);
3225 return CursorVis.VisitChildren(parent);
3226}
3227
3228#ifndef __has_feature
3229#define __has_feature(x) 0
3230#endif
3231#if __has_feature(blocks)
3232typedef enum CXChildVisitResult
3233 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3234
3235static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3236 CXClientData client_data) {
3237 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3238 return block(cursor, parent);
3239}
3240#else
3241// If we are compiled with a compiler that doesn't have native blocks support,
3242// define and call the block manually, so the
3243typedef struct _CXChildVisitResult
3244{
3245 void *isa;
3246 int flags;
3247 int reserved;
3248 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3249 CXCursor);
3250} *CXCursorVisitorBlock;
3251
3252static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3253 CXClientData client_data) {
3254 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3255 return block->invoke(block, cursor, parent);
3256}
3257#endif
3258
3259
3260unsigned clang_visitChildrenWithBlock(CXCursor parent,
3261 CXCursorVisitorBlock block) {
3262 return clang_visitChildren(parent, visitWithBlock, block);
3263}
3264
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003265static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003266 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003267 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003268
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003269 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003270 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003271 if (const ObjCPropertyImplDecl *PropImpl =
3272 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003273 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003274 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003275
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003276 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003277 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003278 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003279
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003280 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003281 }
3282
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003283 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003284 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003285
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003286 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003287 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3288 // and returns different names. NamedDecl returns the class name and
3289 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003290 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003291
3292 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003293 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003294
3295 SmallString<1024> S;
3296 llvm::raw_svector_ostream os(S);
3297 ND->printName(os);
3298
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003299 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003300}
3301
3302CXString clang_getCursorSpelling(CXCursor C) {
3303 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003304 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003305
3306 if (clang_isReference(C.kind)) {
3307 switch (C.kind) {
3308 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003309 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003310 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003311 }
3312 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003313 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003314 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003315 }
3316 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003317 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003318 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003319 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003320 }
3321 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003322 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003323 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003324 }
3325 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003326 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003327 assert(Type && "Missing type decl");
3328
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003329 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003330 getAsString());
3331 }
3332 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003333 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 assert(Template && "Missing template decl");
3335
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003336 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003337 }
3338
3339 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003340 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003341 assert(NS && "Missing namespace decl");
3342
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003343 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003344 }
3345
3346 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003347 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 assert(Field && "Missing member decl");
3349
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003350 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003351 }
3352
3353 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003354 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003355 assert(Label && "Missing label");
3356
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003357 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003358 }
3359
3360 case CXCursor_OverloadedDeclRef: {
3361 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003362 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3363 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003364 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003365 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003366 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003367 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003368 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003369 OverloadedTemplateStorage *Ovl
3370 = Storage.get<OverloadedTemplateStorage*>();
3371 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003372 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003373 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003374 }
3375
3376 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003377 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 assert(Var && "Missing variable decl");
3379
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003380 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003381 }
3382
3383 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003384 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003385 }
3386 }
3387
3388 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003389 const Expr *E = getCursorExpr(C);
3390
3391 if (C.kind == CXCursor_ObjCStringLiteral ||
3392 C.kind == CXCursor_StringLiteral) {
3393 const StringLiteral *SLit;
3394 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3395 SLit = OSL->getString();
3396 } else {
3397 SLit = cast<StringLiteral>(E);
3398 }
3399 SmallString<256> Buf;
3400 llvm::raw_svector_ostream OS(Buf);
3401 SLit->outputString(OS);
3402 return cxstring::createDup(OS.str());
3403 }
3404
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003405 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003406 if (D)
3407 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003408 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003409 }
3410
3411 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003412 const Stmt *S = getCursorStmt(C);
3413 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003414 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003415
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003416 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003417 }
3418
3419 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003420 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003421 ->getNameStart());
3422
3423 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003424 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003425 ->getNameStart());
3426
3427 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003428 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003429
3430 if (clang_isDeclaration(C.kind))
3431 return getDeclSpelling(getCursorDecl(C));
3432
3433 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003434 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003435 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003436 }
3437
3438 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003439 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003440 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003441 }
3442
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003443 if (C.kind == CXCursor_PackedAttr) {
3444 return cxstring::createRef("packed");
3445 }
3446
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003447 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003448}
3449
3450CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3451 unsigned pieceIndex,
3452 unsigned options) {
3453 if (clang_Cursor_isNull(C))
3454 return clang_getNullRange();
3455
3456 ASTContext &Ctx = getCursorContext(C);
3457
3458 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003459 const Stmt *S = getCursorStmt(C);
3460 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003461 if (pieceIndex > 0)
3462 return clang_getNullRange();
3463 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3464 }
3465
3466 return clang_getNullRange();
3467 }
3468
3469 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003470 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003471 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3472 if (pieceIndex >= ME->getNumSelectorLocs())
3473 return clang_getNullRange();
3474 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3475 }
3476 }
3477
3478 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3479 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003480 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003481 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3482 if (pieceIndex >= MD->getNumSelectorLocs())
3483 return clang_getNullRange();
3484 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3485 }
3486 }
3487
3488 if (C.kind == CXCursor_ObjCCategoryDecl ||
3489 C.kind == CXCursor_ObjCCategoryImplDecl) {
3490 if (pieceIndex > 0)
3491 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003492 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003493 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3494 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003495 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003496 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3497 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3498 }
3499
3500 if (C.kind == CXCursor_ModuleImportDecl) {
3501 if (pieceIndex > 0)
3502 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003503 if (const ImportDecl *ImportD =
3504 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003505 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3506 if (!Locs.empty())
3507 return cxloc::translateSourceRange(Ctx,
3508 SourceRange(Locs.front(), Locs.back()));
3509 }
3510 return clang_getNullRange();
3511 }
3512
3513 // FIXME: A CXCursor_InclusionDirective should give the location of the
3514 // filename, but we don't keep track of this.
3515
3516 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3517 // but we don't keep track of this.
3518
3519 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3520 // but we don't keep track of this.
3521
3522 // Default handling, give the location of the cursor.
3523
3524 if (pieceIndex > 0)
3525 return clang_getNullRange();
3526
3527 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3528 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3529 return cxloc::translateSourceRange(Ctx, Loc);
3530}
3531
3532CXString clang_getCursorDisplayName(CXCursor C) {
3533 if (!clang_isDeclaration(C.kind))
3534 return clang_getCursorSpelling(C);
3535
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003536 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003537 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003538 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003539
3540 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003541 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003542 D = FunTmpl->getTemplatedDecl();
3543
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003544 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 SmallString<64> Str;
3546 llvm::raw_svector_ostream OS(Str);
3547 OS << *Function;
3548 if (Function->getPrimaryTemplate())
3549 OS << "<>";
3550 OS << "(";
3551 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3552 if (I)
3553 OS << ", ";
3554 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3555 }
3556
3557 if (Function->isVariadic()) {
3558 if (Function->getNumParams())
3559 OS << ", ";
3560 OS << "...";
3561 }
3562 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003563 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003564 }
3565
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003566 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003567 SmallString<64> Str;
3568 llvm::raw_svector_ostream OS(Str);
3569 OS << *ClassTemplate;
3570 OS << "<";
3571 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3572 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3573 if (I)
3574 OS << ", ";
3575
3576 NamedDecl *Param = Params->getParam(I);
3577 if (Param->getIdentifier()) {
3578 OS << Param->getIdentifier()->getName();
3579 continue;
3580 }
3581
3582 // There is no parameter name, which makes this tricky. Try to come up
3583 // with something useful that isn't too long.
3584 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3585 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3586 else if (NonTypeTemplateParmDecl *NTTP
3587 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3588 OS << NTTP->getType().getAsString(Policy);
3589 else
3590 OS << "template<...> class";
3591 }
3592
3593 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003594 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003595 }
3596
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003597 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003598 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3599 // If the type was explicitly written, use that.
3600 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003601 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003602
Benjamin Kramer9170e912013-02-22 15:46:01 +00003603 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003604 llvm::raw_svector_ostream OS(Str);
3605 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003606 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003607 ClassSpec->getTemplateArgs().data(),
3608 ClassSpec->getTemplateArgs().size(),
3609 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003610 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003611 }
3612
3613 return clang_getCursorSpelling(C);
3614}
3615
3616CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3617 switch (Kind) {
3618 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003619 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003620 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003621 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003622 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003623 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003624 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003625 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003626 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003627 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003628 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003629 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003630 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003631 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003632 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003633 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003635 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003637 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003641 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003643 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003645 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003647 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003651 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003653 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003655 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003659 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003663 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003665 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003673 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003746 case CXCursor_ObjCSelfExpr:
3747 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003864 case CXCursor_PackedAttr:
3865 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003914 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003915 return cxstring::createRef("OMPParallelDirective");
3916 case CXCursor_OMPSimdDirective:
3917 return cxstring::createRef("OMPSimdDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 }
3919
3920 llvm_unreachable("Unhandled CXCursorKind");
3921}
3922
3923struct GetCursorData {
3924 SourceLocation TokenBeginLoc;
3925 bool PointsAtMacroArgExpansion;
3926 bool VisitedObjCPropertyImplDecl;
3927 SourceLocation VisitedDeclaratorDeclStartLoc;
3928 CXCursor &BestCursor;
3929
3930 GetCursorData(SourceManager &SM,
3931 SourceLocation tokenBegin, CXCursor &outputCursor)
3932 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3933 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3934 VisitedObjCPropertyImplDecl = false;
3935 }
3936};
3937
3938static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3939 CXCursor parent,
3940 CXClientData client_data) {
3941 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3942 CXCursor *BestCursor = &Data->BestCursor;
3943
3944 // If we point inside a macro argument we should provide info of what the
3945 // token is so use the actual cursor, don't replace it with a macro expansion
3946 // cursor.
3947 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3948 return CXChildVisit_Recurse;
3949
3950 if (clang_isDeclaration(cursor.kind)) {
3951 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003952 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003953 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3954 if (MD->isImplicit())
3955 return CXChildVisit_Break;
3956
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003957 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3959 // Check that when we have multiple @class references in the same line,
3960 // that later ones do not override the previous ones.
3961 // If we have:
3962 // @class Foo, Bar;
3963 // source ranges for both start at '@', so 'Bar' will end up overriding
3964 // 'Foo' even though the cursor location was at 'Foo'.
3965 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3966 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003967 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3969 if (PrevID != ID &&
3970 !PrevID->isThisDeclarationADefinition() &&
3971 !ID->isThisDeclarationADefinition())
3972 return CXChildVisit_Break;
3973 }
3974
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003975 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003976 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3977 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3978 // Check that when we have multiple declarators in the same line,
3979 // that later ones do not override the previous ones.
3980 // If we have:
3981 // int Foo, Bar;
3982 // source ranges for both start at 'int', so 'Bar' will end up overriding
3983 // 'Foo' even though the cursor location was at 'Foo'.
3984 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3985 return CXChildVisit_Break;
3986 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3987
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003988 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003989 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3990 (void)PropImp;
3991 // Check that when we have multiple @synthesize in the same line,
3992 // that later ones do not override the previous ones.
3993 // If we have:
3994 // @synthesize Foo, Bar;
3995 // source ranges for both start at '@', so 'Bar' will end up overriding
3996 // 'Foo' even though the cursor location was at 'Foo'.
3997 if (Data->VisitedObjCPropertyImplDecl)
3998 return CXChildVisit_Break;
3999 Data->VisitedObjCPropertyImplDecl = true;
4000 }
4001 }
4002
4003 if (clang_isExpression(cursor.kind) &&
4004 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004005 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004006 // Avoid having the cursor of an expression replace the declaration cursor
4007 // when the expression source range overlaps the declaration range.
4008 // This can happen for C++ constructor expressions whose range generally
4009 // include the variable declaration, e.g.:
4010 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4011 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4012 D->getLocation() == Data->TokenBeginLoc)
4013 return CXChildVisit_Break;
4014 }
4015 }
4016
4017 // If our current best cursor is the construction of a temporary object,
4018 // don't replace that cursor with a type reference, because we want
4019 // clang_getCursor() to point at the constructor.
4020 if (clang_isExpression(BestCursor->kind) &&
4021 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4022 cursor.kind == CXCursor_TypeRef) {
4023 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4024 // as having the actual point on the type reference.
4025 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4026 return CXChildVisit_Recurse;
4027 }
4028
4029 *BestCursor = cursor;
4030 return CXChildVisit_Recurse;
4031}
4032
4033CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004034 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004035 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004036 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004037 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004038
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004039 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4041
4042 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4043 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4044
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004045 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 CXFile SearchFile;
4047 unsigned SearchLine, SearchColumn;
4048 CXFile ResultFile;
4049 unsigned ResultLine, ResultColumn;
4050 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4051 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4052 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4053
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004054 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4055 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 &ResultColumn, 0);
4057 SearchFileName = clang_getFileName(SearchFile);
4058 ResultFileName = clang_getFileName(ResultFile);
4059 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4060 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004061 *Log << llvm::format("(%s:%d:%d) = %s",
4062 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4063 clang_getCString(KindSpelling))
4064 << llvm::format("(%s:%d:%d):%s%s",
4065 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4066 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004067 clang_disposeString(SearchFileName);
4068 clang_disposeString(ResultFileName);
4069 clang_disposeString(KindSpelling);
4070 clang_disposeString(USR);
4071
4072 CXCursor Definition = clang_getCursorDefinition(Result);
4073 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4074 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4075 CXString DefinitionKindSpelling
4076 = clang_getCursorKindSpelling(Definition.kind);
4077 CXFile DefinitionFile;
4078 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004079 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004080 &DefinitionLine, &DefinitionColumn, 0);
4081 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004082 *Log << llvm::format(" -> %s(%s:%d:%d)",
4083 clang_getCString(DefinitionKindSpelling),
4084 clang_getCString(DefinitionFileName),
4085 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004086 clang_disposeString(DefinitionFileName);
4087 clang_disposeString(DefinitionKindSpelling);
4088 }
4089 }
4090
4091 return Result;
4092}
4093
4094CXCursor clang_getNullCursor(void) {
4095 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4096}
4097
4098unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004099 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4100 // can't set consistently. For example, when visiting a DeclStmt we will set
4101 // it but we don't set it on the result of clang_getCursorDefinition for
4102 // a reference of the same declaration.
4103 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4104 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4105 // to provide that kind of info.
4106 if (clang_isDeclaration(X.kind))
4107 X.data[1] = 0;
4108 if (clang_isDeclaration(Y.kind))
4109 Y.data[1] = 0;
4110
Guy Benyei11169dd2012-12-18 14:30:41 +00004111 return X == Y;
4112}
4113
4114unsigned clang_hashCursor(CXCursor C) {
4115 unsigned Index = 0;
4116 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4117 Index = 1;
4118
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004119 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004120 std::make_pair(C.kind, C.data[Index]));
4121}
4122
4123unsigned clang_isInvalid(enum CXCursorKind K) {
4124 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4125}
4126
4127unsigned clang_isDeclaration(enum CXCursorKind K) {
4128 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4129 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4130}
4131
4132unsigned clang_isReference(enum CXCursorKind K) {
4133 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4134}
4135
4136unsigned clang_isExpression(enum CXCursorKind K) {
4137 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4138}
4139
4140unsigned clang_isStatement(enum CXCursorKind K) {
4141 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4142}
4143
4144unsigned clang_isAttribute(enum CXCursorKind K) {
4145 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4146}
4147
4148unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4149 return K == CXCursor_TranslationUnit;
4150}
4151
4152unsigned clang_isPreprocessing(enum CXCursorKind K) {
4153 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4154}
4155
4156unsigned clang_isUnexposed(enum CXCursorKind K) {
4157 switch (K) {
4158 case CXCursor_UnexposedDecl:
4159 case CXCursor_UnexposedExpr:
4160 case CXCursor_UnexposedStmt:
4161 case CXCursor_UnexposedAttr:
4162 return true;
4163 default:
4164 return false;
4165 }
4166}
4167
4168CXCursorKind clang_getCursorKind(CXCursor C) {
4169 return C.kind;
4170}
4171
4172CXSourceLocation clang_getCursorLocation(CXCursor C) {
4173 if (clang_isReference(C.kind)) {
4174 switch (C.kind) {
4175 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004176 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004177 = getCursorObjCSuperClassRef(C);
4178 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4179 }
4180
4181 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004182 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004183 = getCursorObjCProtocolRef(C);
4184 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4185 }
4186
4187 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004188 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 = getCursorObjCClassRef(C);
4190 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4191 }
4192
4193 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004194 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4196 }
4197
4198 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004199 std::pair<const TemplateDecl *, SourceLocation> P =
4200 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4202 }
4203
4204 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004205 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4207 }
4208
4209 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004210 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4212 }
4213
4214 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004215 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4217 }
4218
4219 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004220 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004221 if (!BaseSpec)
4222 return clang_getNullLocation();
4223
4224 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4225 return cxloc::translateSourceLocation(getCursorContext(C),
4226 TSInfo->getTypeLoc().getBeginLoc());
4227
4228 return cxloc::translateSourceLocation(getCursorContext(C),
4229 BaseSpec->getLocStart());
4230 }
4231
4232 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004233 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004234 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4235 }
4236
4237 case CXCursor_OverloadedDeclRef:
4238 return cxloc::translateSourceLocation(getCursorContext(C),
4239 getCursorOverloadedDeclRef(C).second);
4240
4241 default:
4242 // FIXME: Need a way to enumerate all non-reference cases.
4243 llvm_unreachable("Missed a reference kind");
4244 }
4245 }
4246
4247 if (clang_isExpression(C.kind))
4248 return cxloc::translateSourceLocation(getCursorContext(C),
4249 getLocationFromExpr(getCursorExpr(C)));
4250
4251 if (clang_isStatement(C.kind))
4252 return cxloc::translateSourceLocation(getCursorContext(C),
4253 getCursorStmt(C)->getLocStart());
4254
4255 if (C.kind == CXCursor_PreprocessingDirective) {
4256 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4257 return cxloc::translateSourceLocation(getCursorContext(C), L);
4258 }
4259
4260 if (C.kind == CXCursor_MacroExpansion) {
4261 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004262 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004263 return cxloc::translateSourceLocation(getCursorContext(C), L);
4264 }
4265
4266 if (C.kind == CXCursor_MacroDefinition) {
4267 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4268 return cxloc::translateSourceLocation(getCursorContext(C), L);
4269 }
4270
4271 if (C.kind == CXCursor_InclusionDirective) {
4272 SourceLocation L
4273 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4274 return cxloc::translateSourceLocation(getCursorContext(C), L);
4275 }
4276
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004277 if (clang_isAttribute(C.kind)) {
4278 SourceLocation L
4279 = cxcursor::getCursorAttr(C)->getLocation();
4280 return cxloc::translateSourceLocation(getCursorContext(C), L);
4281 }
4282
Guy Benyei11169dd2012-12-18 14:30:41 +00004283 if (!clang_isDeclaration(C.kind))
4284 return clang_getNullLocation();
4285
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004286 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004287 if (!D)
4288 return clang_getNullLocation();
4289
4290 SourceLocation Loc = D->getLocation();
4291 // FIXME: Multiple variables declared in a single declaration
4292 // currently lack the information needed to correctly determine their
4293 // ranges when accounting for the type-specifier. We use context
4294 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4295 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004296 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004297 if (!cxcursor::isFirstInDeclGroup(C))
4298 Loc = VD->getLocation();
4299 }
4300
4301 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004302 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004303 Loc = MD->getSelectorStartLoc();
4304
4305 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4306}
4307
4308} // end extern "C"
4309
4310CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4311 assert(TU);
4312
4313 // Guard against an invalid SourceLocation, or we may assert in one
4314 // of the following calls.
4315 if (SLoc.isInvalid())
4316 return clang_getNullCursor();
4317
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004318 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004319
4320 // Translate the given source location to make it point at the beginning of
4321 // the token under the cursor.
4322 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4323 CXXUnit->getASTContext().getLangOpts());
4324
4325 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4326 if (SLoc.isValid()) {
4327 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4328 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4329 /*VisitPreprocessorLast=*/true,
4330 /*VisitIncludedEntities=*/false,
4331 SourceLocation(SLoc));
4332 CursorVis.visitFileRegion();
4333 }
4334
4335 return Result;
4336}
4337
4338static SourceRange getRawCursorExtent(CXCursor C) {
4339 if (clang_isReference(C.kind)) {
4340 switch (C.kind) {
4341 case CXCursor_ObjCSuperClassRef:
4342 return getCursorObjCSuperClassRef(C).second;
4343
4344 case CXCursor_ObjCProtocolRef:
4345 return getCursorObjCProtocolRef(C).second;
4346
4347 case CXCursor_ObjCClassRef:
4348 return getCursorObjCClassRef(C).second;
4349
4350 case CXCursor_TypeRef:
4351 return getCursorTypeRef(C).second;
4352
4353 case CXCursor_TemplateRef:
4354 return getCursorTemplateRef(C).second;
4355
4356 case CXCursor_NamespaceRef:
4357 return getCursorNamespaceRef(C).second;
4358
4359 case CXCursor_MemberRef:
4360 return getCursorMemberRef(C).second;
4361
4362 case CXCursor_CXXBaseSpecifier:
4363 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4364
4365 case CXCursor_LabelRef:
4366 return getCursorLabelRef(C).second;
4367
4368 case CXCursor_OverloadedDeclRef:
4369 return getCursorOverloadedDeclRef(C).second;
4370
4371 case CXCursor_VariableRef:
4372 return getCursorVariableRef(C).second;
4373
4374 default:
4375 // FIXME: Need a way to enumerate all non-reference cases.
4376 llvm_unreachable("Missed a reference kind");
4377 }
4378 }
4379
4380 if (clang_isExpression(C.kind))
4381 return getCursorExpr(C)->getSourceRange();
4382
4383 if (clang_isStatement(C.kind))
4384 return getCursorStmt(C)->getSourceRange();
4385
4386 if (clang_isAttribute(C.kind))
4387 return getCursorAttr(C)->getRange();
4388
4389 if (C.kind == CXCursor_PreprocessingDirective)
4390 return cxcursor::getCursorPreprocessingDirective(C);
4391
4392 if (C.kind == CXCursor_MacroExpansion) {
4393 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004394 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004395 return TU->mapRangeFromPreamble(Range);
4396 }
4397
4398 if (C.kind == CXCursor_MacroDefinition) {
4399 ASTUnit *TU = getCursorASTUnit(C);
4400 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4401 return TU->mapRangeFromPreamble(Range);
4402 }
4403
4404 if (C.kind == CXCursor_InclusionDirective) {
4405 ASTUnit *TU = getCursorASTUnit(C);
4406 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4407 return TU->mapRangeFromPreamble(Range);
4408 }
4409
4410 if (C.kind == CXCursor_TranslationUnit) {
4411 ASTUnit *TU = getCursorASTUnit(C);
4412 FileID MainID = TU->getSourceManager().getMainFileID();
4413 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4414 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4415 return SourceRange(Start, End);
4416 }
4417
4418 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004419 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004420 if (!D)
4421 return SourceRange();
4422
4423 SourceRange R = D->getSourceRange();
4424 // FIXME: Multiple variables declared in a single declaration
4425 // currently lack the information needed to correctly determine their
4426 // ranges when accounting for the type-specifier. We use context
4427 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4428 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004429 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004430 if (!cxcursor::isFirstInDeclGroup(C))
4431 R.setBegin(VD->getLocation());
4432 }
4433 return R;
4434 }
4435 return SourceRange();
4436}
4437
4438/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4439/// the decl-specifier-seq for declarations.
4440static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4441 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004442 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004443 if (!D)
4444 return SourceRange();
4445
4446 SourceRange R = D->getSourceRange();
4447
4448 // Adjust the start of the location for declarations preceded by
4449 // declaration specifiers.
4450 SourceLocation StartLoc;
4451 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4452 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4453 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004454 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004455 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4456 StartLoc = TI->getTypeLoc().getLocStart();
4457 }
4458
4459 if (StartLoc.isValid() && R.getBegin().isValid() &&
4460 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4461 R.setBegin(StartLoc);
4462
4463 // FIXME: Multiple variables declared in a single declaration
4464 // currently lack the information needed to correctly determine their
4465 // ranges when accounting for the type-specifier. We use context
4466 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4467 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004468 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004469 if (!cxcursor::isFirstInDeclGroup(C))
4470 R.setBegin(VD->getLocation());
4471 }
4472
4473 return R;
4474 }
4475
4476 return getRawCursorExtent(C);
4477}
4478
4479extern "C" {
4480
4481CXSourceRange clang_getCursorExtent(CXCursor C) {
4482 SourceRange R = getRawCursorExtent(C);
4483 if (R.isInvalid())
4484 return clang_getNullRange();
4485
4486 return cxloc::translateSourceRange(getCursorContext(C), R);
4487}
4488
4489CXCursor clang_getCursorReferenced(CXCursor C) {
4490 if (clang_isInvalid(C.kind))
4491 return clang_getNullCursor();
4492
4493 CXTranslationUnit tu = getCursorTU(C);
4494 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004495 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004496 if (!D)
4497 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004498 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004499 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004500 if (const ObjCPropertyImplDecl *PropImpl =
4501 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004502 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4503 return MakeCXCursor(Property, tu);
4504
4505 return C;
4506 }
4507
4508 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004509 const Expr *E = getCursorExpr(C);
4510 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004511 if (D) {
4512 CXCursor declCursor = MakeCXCursor(D, tu);
4513 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4514 declCursor);
4515 return declCursor;
4516 }
4517
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004518 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004519 return MakeCursorOverloadedDeclRef(Ovl, tu);
4520
4521 return clang_getNullCursor();
4522 }
4523
4524 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004525 const Stmt *S = getCursorStmt(C);
4526 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004527 if (LabelDecl *label = Goto->getLabel())
4528 if (LabelStmt *labelS = label->getStmt())
4529 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4530
4531 return clang_getNullCursor();
4532 }
4533
4534 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004535 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004536 return MakeMacroDefinitionCursor(Def, tu);
4537 }
4538
4539 if (!clang_isReference(C.kind))
4540 return clang_getNullCursor();
4541
4542 switch (C.kind) {
4543 case CXCursor_ObjCSuperClassRef:
4544 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4545
4546 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004547 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4548 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004549 return MakeCXCursor(Def, tu);
4550
4551 return MakeCXCursor(Prot, tu);
4552 }
4553
4554 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004555 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4556 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004557 return MakeCXCursor(Def, tu);
4558
4559 return MakeCXCursor(Class, tu);
4560 }
4561
4562 case CXCursor_TypeRef:
4563 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4564
4565 case CXCursor_TemplateRef:
4566 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4567
4568 case CXCursor_NamespaceRef:
4569 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4570
4571 case CXCursor_MemberRef:
4572 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4573
4574 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004575 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004576 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4577 tu ));
4578 }
4579
4580 case CXCursor_LabelRef:
4581 // FIXME: We end up faking the "parent" declaration here because we
4582 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004583 return MakeCXCursor(getCursorLabelRef(C).first,
4584 cxtu::getASTUnit(tu)->getASTContext()
4585 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004586 tu);
4587
4588 case CXCursor_OverloadedDeclRef:
4589 return C;
4590
4591 case CXCursor_VariableRef:
4592 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4593
4594 default:
4595 // We would prefer to enumerate all non-reference cursor kinds here.
4596 llvm_unreachable("Unhandled reference cursor kind");
4597 }
4598}
4599
4600CXCursor clang_getCursorDefinition(CXCursor C) {
4601 if (clang_isInvalid(C.kind))
4602 return clang_getNullCursor();
4603
4604 CXTranslationUnit TU = getCursorTU(C);
4605
4606 bool WasReference = false;
4607 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4608 C = clang_getCursorReferenced(C);
4609 WasReference = true;
4610 }
4611
4612 if (C.kind == CXCursor_MacroExpansion)
4613 return clang_getCursorReferenced(C);
4614
4615 if (!clang_isDeclaration(C.kind))
4616 return clang_getNullCursor();
4617
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004618 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004619 if (!D)
4620 return clang_getNullCursor();
4621
4622 switch (D->getKind()) {
4623 // Declaration kinds that don't really separate the notions of
4624 // declaration and definition.
4625 case Decl::Namespace:
4626 case Decl::Typedef:
4627 case Decl::TypeAlias:
4628 case Decl::TypeAliasTemplate:
4629 case Decl::TemplateTypeParm:
4630 case Decl::EnumConstant:
4631 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004632 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004633 case Decl::IndirectField:
4634 case Decl::ObjCIvar:
4635 case Decl::ObjCAtDefsField:
4636 case Decl::ImplicitParam:
4637 case Decl::ParmVar:
4638 case Decl::NonTypeTemplateParm:
4639 case Decl::TemplateTemplateParm:
4640 case Decl::ObjCCategoryImpl:
4641 case Decl::ObjCImplementation:
4642 case Decl::AccessSpec:
4643 case Decl::LinkageSpec:
4644 case Decl::ObjCPropertyImpl:
4645 case Decl::FileScopeAsm:
4646 case Decl::StaticAssert:
4647 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004648 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004649 case Decl::Label: // FIXME: Is this right??
4650 case Decl::ClassScopeFunctionSpecialization:
4651 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004652 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 return C;
4654
4655 // Declaration kinds that don't make any sense here, but are
4656 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004657 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004658 case Decl::TranslationUnit:
4659 break;
4660
4661 // Declaration kinds for which the definition is not resolvable.
4662 case Decl::UnresolvedUsingTypename:
4663 case Decl::UnresolvedUsingValue:
4664 break;
4665
4666 case Decl::UsingDirective:
4667 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4668 TU);
4669
4670 case Decl::NamespaceAlias:
4671 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4672
4673 case Decl::Enum:
4674 case Decl::Record:
4675 case Decl::CXXRecord:
4676 case Decl::ClassTemplateSpecialization:
4677 case Decl::ClassTemplatePartialSpecialization:
4678 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4679 return MakeCXCursor(Def, TU);
4680 return clang_getNullCursor();
4681
4682 case Decl::Function:
4683 case Decl::CXXMethod:
4684 case Decl::CXXConstructor:
4685 case Decl::CXXDestructor:
4686 case Decl::CXXConversion: {
4687 const FunctionDecl *Def = 0;
4688 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004689 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004690 return clang_getNullCursor();
4691 }
4692
Larisse Voufo39a1e502013-08-06 01:03:05 +00004693 case Decl::Var:
4694 case Decl::VarTemplateSpecialization:
4695 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004696 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004697 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004698 return MakeCXCursor(Def, TU);
4699 return clang_getNullCursor();
4700 }
4701
4702 case Decl::FunctionTemplate: {
4703 const FunctionDecl *Def = 0;
4704 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4705 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4706 return clang_getNullCursor();
4707 }
4708
4709 case Decl::ClassTemplate: {
4710 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4711 ->getDefinition())
4712 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4713 TU);
4714 return clang_getNullCursor();
4715 }
4716
Larisse Voufo39a1e502013-08-06 01:03:05 +00004717 case Decl::VarTemplate: {
4718 if (VarDecl *Def =
4719 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4720 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4721 return clang_getNullCursor();
4722 }
4723
Guy Benyei11169dd2012-12-18 14:30:41 +00004724 case Decl::Using:
4725 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4726 D->getLocation(), TU);
4727
4728 case Decl::UsingShadow:
4729 return clang_getCursorDefinition(
4730 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4731 TU));
4732
4733 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004734 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004735 if (Method->isThisDeclarationADefinition())
4736 return C;
4737
4738 // Dig out the method definition in the associated
4739 // @implementation, if we have it.
4740 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004741 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004742 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4743 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4744 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4745 Method->isInstanceMethod()))
4746 if (Def->isThisDeclarationADefinition())
4747 return MakeCXCursor(Def, TU);
4748
4749 return clang_getNullCursor();
4750 }
4751
4752 case Decl::ObjCCategory:
4753 if (ObjCCategoryImplDecl *Impl
4754 = cast<ObjCCategoryDecl>(D)->getImplementation())
4755 return MakeCXCursor(Impl, TU);
4756 return clang_getNullCursor();
4757
4758 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004759 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004760 return MakeCXCursor(Def, TU);
4761 return clang_getNullCursor();
4762
4763 case Decl::ObjCInterface: {
4764 // There are two notions of a "definition" for an Objective-C
4765 // class: the interface and its implementation. When we resolved a
4766 // reference to an Objective-C class, produce the @interface as
4767 // the definition; when we were provided with the interface,
4768 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004769 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004770 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004771 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004772 return MakeCXCursor(Def, TU);
4773 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4774 return MakeCXCursor(Impl, TU);
4775 return clang_getNullCursor();
4776 }
4777
4778 case Decl::ObjCProperty:
4779 // FIXME: We don't really know where to find the
4780 // ObjCPropertyImplDecls that implement this property.
4781 return clang_getNullCursor();
4782
4783 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004784 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004785 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004786 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004787 return MakeCXCursor(Def, TU);
4788
4789 return clang_getNullCursor();
4790
4791 case Decl::Friend:
4792 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4793 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4794 return clang_getNullCursor();
4795
4796 case Decl::FriendTemplate:
4797 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4798 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4799 return clang_getNullCursor();
4800 }
4801
4802 return clang_getNullCursor();
4803}
4804
4805unsigned clang_isCursorDefinition(CXCursor C) {
4806 if (!clang_isDeclaration(C.kind))
4807 return 0;
4808
4809 return clang_getCursorDefinition(C) == C;
4810}
4811
4812CXCursor clang_getCanonicalCursor(CXCursor C) {
4813 if (!clang_isDeclaration(C.kind))
4814 return C;
4815
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004816 if (const Decl *D = getCursorDecl(C)) {
4817 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004818 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4819 return MakeCXCursor(CatD, getCursorTU(C));
4820
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004821 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4822 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004823 return MakeCXCursor(IFD, getCursorTU(C));
4824
4825 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4826 }
4827
4828 return C;
4829}
4830
4831int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4832 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4833}
4834
4835unsigned clang_getNumOverloadedDecls(CXCursor C) {
4836 if (C.kind != CXCursor_OverloadedDeclRef)
4837 return 0;
4838
4839 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004840 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004841 return E->getNumDecls();
4842
4843 if (OverloadedTemplateStorage *S
4844 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4845 return S->size();
4846
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004847 const Decl *D = Storage.get<const Decl *>();
4848 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004849 return Using->shadow_size();
4850
4851 return 0;
4852}
4853
4854CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4855 if (cursor.kind != CXCursor_OverloadedDeclRef)
4856 return clang_getNullCursor();
4857
4858 if (index >= clang_getNumOverloadedDecls(cursor))
4859 return clang_getNullCursor();
4860
4861 CXTranslationUnit TU = getCursorTU(cursor);
4862 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004863 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004864 return MakeCXCursor(E->decls_begin()[index], TU);
4865
4866 if (OverloadedTemplateStorage *S
4867 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4868 return MakeCXCursor(S->begin()[index], TU);
4869
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004870 const Decl *D = Storage.get<const Decl *>();
4871 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004872 // FIXME: This is, unfortunately, linear time.
4873 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4874 std::advance(Pos, index);
4875 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4876 }
4877
4878 return clang_getNullCursor();
4879}
4880
4881void clang_getDefinitionSpellingAndExtent(CXCursor C,
4882 const char **startBuf,
4883 const char **endBuf,
4884 unsigned *startLine,
4885 unsigned *startColumn,
4886 unsigned *endLine,
4887 unsigned *endColumn) {
4888 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004889 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004890 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4891
4892 SourceManager &SM = FD->getASTContext().getSourceManager();
4893 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4894 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4895 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4896 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4897 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4898 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4899}
4900
4901
4902CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4903 unsigned PieceIndex) {
4904 RefNamePieces Pieces;
4905
4906 switch (C.kind) {
4907 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004908 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004909 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4910 E->getQualifierLoc().getSourceRange());
4911 break;
4912
4913 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004914 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004915 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4916 E->getQualifierLoc().getSourceRange(),
4917 E->getOptionalExplicitTemplateArgs());
4918 break;
4919
4920 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004921 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004922 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004923 const Expr *Callee = OCE->getCallee();
4924 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004925 Callee = ICE->getSubExpr();
4926
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004927 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004928 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4929 DRE->getQualifierLoc().getSourceRange());
4930 }
4931 break;
4932
4933 default:
4934 break;
4935 }
4936
4937 if (Pieces.empty()) {
4938 if (PieceIndex == 0)
4939 return clang_getCursorExtent(C);
4940 } else if (PieceIndex < Pieces.size()) {
4941 SourceRange R = Pieces[PieceIndex];
4942 if (R.isValid())
4943 return cxloc::translateSourceRange(getCursorContext(C), R);
4944 }
4945
4946 return clang_getNullRange();
4947}
4948
4949void clang_enableStackTraces(void) {
4950 llvm::sys::PrintStackTraceOnErrorSignal();
4951}
4952
4953void clang_executeOnThread(void (*fn)(void*), void *user_data,
4954 unsigned stack_size) {
4955 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4956}
4957
4958} // end: extern "C"
4959
4960//===----------------------------------------------------------------------===//
4961// Token-based Operations.
4962//===----------------------------------------------------------------------===//
4963
4964/* CXToken layout:
4965 * int_data[0]: a CXTokenKind
4966 * int_data[1]: starting token location
4967 * int_data[2]: token length
4968 * int_data[3]: reserved
4969 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4970 * otherwise unused.
4971 */
4972extern "C" {
4973
4974CXTokenKind clang_getTokenKind(CXToken CXTok) {
4975 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4976}
4977
4978CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4979 switch (clang_getTokenKind(CXTok)) {
4980 case CXToken_Identifier:
4981 case CXToken_Keyword:
4982 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004983 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004984 ->getNameStart());
4985
4986 case CXToken_Literal: {
4987 // We have stashed the starting pointer in the ptr_data field. Use it.
4988 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004989 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004990 }
4991
4992 case CXToken_Punctuation:
4993 case CXToken_Comment:
4994 break;
4995 }
4996
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004997 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004998 LOG_BAD_TU(TU);
4999 return cxstring::createEmpty();
5000 }
5001
Guy Benyei11169dd2012-12-18 14:30:41 +00005002 // We have to find the starting buffer pointer the hard way, by
5003 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005004 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005005 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005006 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005007
5008 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5009 std::pair<FileID, unsigned> LocInfo
5010 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5011 bool Invalid = false;
5012 StringRef Buffer
5013 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5014 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005015 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005016
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005017 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005018}
5019
5020CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005021 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005022 LOG_BAD_TU(TU);
5023 return clang_getNullLocation();
5024 }
5025
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005026 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005027 if (!CXXUnit)
5028 return clang_getNullLocation();
5029
5030 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5031 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5032}
5033
5034CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005035 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005036 LOG_BAD_TU(TU);
5037 return clang_getNullRange();
5038 }
5039
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005040 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005041 if (!CXXUnit)
5042 return clang_getNullRange();
5043
5044 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5045 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5046}
5047
5048static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5049 SmallVectorImpl<CXToken> &CXTokens) {
5050 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5051 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005052 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005053 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005054 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005055
5056 // Cannot tokenize across files.
5057 if (BeginLocInfo.first != EndLocInfo.first)
5058 return;
5059
5060 // Create a lexer
5061 bool Invalid = false;
5062 StringRef Buffer
5063 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5064 if (Invalid)
5065 return;
5066
5067 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5068 CXXUnit->getASTContext().getLangOpts(),
5069 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5070 Lex.SetCommentRetentionState(true);
5071
5072 // Lex tokens until we hit the end of the range.
5073 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5074 Token Tok;
5075 bool previousWasAt = false;
5076 do {
5077 // Lex the next token
5078 Lex.LexFromRawLexer(Tok);
5079 if (Tok.is(tok::eof))
5080 break;
5081
5082 // Initialize the CXToken.
5083 CXToken CXTok;
5084
5085 // - Common fields
5086 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5087 CXTok.int_data[2] = Tok.getLength();
5088 CXTok.int_data[3] = 0;
5089
5090 // - Kind-specific fields
5091 if (Tok.isLiteral()) {
5092 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005093 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005094 } else if (Tok.is(tok::raw_identifier)) {
5095 // Lookup the identifier to determine whether we have a keyword.
5096 IdentifierInfo *II
5097 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5098
5099 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5100 CXTok.int_data[0] = CXToken_Keyword;
5101 }
5102 else {
5103 CXTok.int_data[0] = Tok.is(tok::identifier)
5104 ? CXToken_Identifier
5105 : CXToken_Keyword;
5106 }
5107 CXTok.ptr_data = II;
5108 } else if (Tok.is(tok::comment)) {
5109 CXTok.int_data[0] = CXToken_Comment;
5110 CXTok.ptr_data = 0;
5111 } else {
5112 CXTok.int_data[0] = CXToken_Punctuation;
5113 CXTok.ptr_data = 0;
5114 }
5115 CXTokens.push_back(CXTok);
5116 previousWasAt = Tok.is(tok::at);
5117 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5118}
5119
5120void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5121 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005122 LOG_FUNC_SECTION {
5123 *Log << TU << ' ' << Range;
5124 }
5125
Guy Benyei11169dd2012-12-18 14:30:41 +00005126 if (Tokens)
5127 *Tokens = 0;
5128 if (NumTokens)
5129 *NumTokens = 0;
5130
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005131 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005132 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005133 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005134 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005135
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005136 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005137 if (!CXXUnit || !Tokens || !NumTokens)
5138 return;
5139
5140 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5141
5142 SourceRange R = cxloc::translateCXSourceRange(Range);
5143 if (R.isInvalid())
5144 return;
5145
5146 SmallVector<CXToken, 32> CXTokens;
5147 getTokens(CXXUnit, R, CXTokens);
5148
5149 if (CXTokens.empty())
5150 return;
5151
5152 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5153 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5154 *NumTokens = CXTokens.size();
5155}
5156
5157void clang_disposeTokens(CXTranslationUnit TU,
5158 CXToken *Tokens, unsigned NumTokens) {
5159 free(Tokens);
5160}
5161
5162} // end: extern "C"
5163
5164//===----------------------------------------------------------------------===//
5165// Token annotation APIs.
5166//===----------------------------------------------------------------------===//
5167
Guy Benyei11169dd2012-12-18 14:30:41 +00005168static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5169 CXCursor parent,
5170 CXClientData client_data);
5171static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5172 CXClientData client_data);
5173
5174namespace {
5175class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005176 CXToken *Tokens;
5177 CXCursor *Cursors;
5178 unsigned NumTokens;
5179 unsigned TokIdx;
5180 unsigned PreprocessingTokIdx;
5181 CursorVisitor AnnotateVis;
5182 SourceManager &SrcMgr;
5183 bool HasContextSensitiveKeywords;
5184
5185 struct PostChildrenInfo {
5186 CXCursor Cursor;
5187 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005188 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005189 unsigned BeforeChildrenTokenIdx;
5190 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005191 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005192
5193 CXToken &getTok(unsigned Idx) {
5194 assert(Idx < NumTokens);
5195 return Tokens[Idx];
5196 }
5197 const CXToken &getTok(unsigned Idx) const {
5198 assert(Idx < NumTokens);
5199 return Tokens[Idx];
5200 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005201 bool MoreTokens() const { return TokIdx < NumTokens; }
5202 unsigned NextToken() const { return TokIdx; }
5203 void AdvanceToken() { ++TokIdx; }
5204 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005205 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005206 }
5207 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005208 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005209 }
5210 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005211 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005212 }
5213
5214 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005215 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 SourceRange);
5217
5218public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005219 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005220 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005221 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005222 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005223 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 AnnotateTokensVisitor, this,
5225 /*VisitPreprocessorLast=*/true,
5226 /*VisitIncludedEntities=*/false,
5227 RegionOfInterest,
5228 /*VisitDeclsOnly=*/false,
5229 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005230 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005231 HasContextSensitiveKeywords(false) { }
5232
5233 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5234 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5235 bool postVisitChildren(CXCursor cursor);
5236 void AnnotateTokens();
5237
5238 /// \brief Determine whether the annotator saw any cursors that have
5239 /// context-sensitive keywords.
5240 bool hasContextSensitiveKeywords() const {
5241 return HasContextSensitiveKeywords;
5242 }
5243
5244 ~AnnotateTokensWorker() {
5245 assert(PostChildrenInfos.empty());
5246 }
5247};
5248}
5249
5250void AnnotateTokensWorker::AnnotateTokens() {
5251 // Walk the AST within the region of interest, annotating tokens
5252 // along the way.
5253 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005254}
Guy Benyei11169dd2012-12-18 14:30:41 +00005255
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005256static inline void updateCursorAnnotation(CXCursor &Cursor,
5257 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005258 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005259 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005260 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005261}
5262
5263/// \brief It annotates and advances tokens with a cursor until the comparison
5264//// between the cursor location and the source range is the same as
5265/// \arg compResult.
5266///
5267/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5268/// Pass RangeOverlap to annotate tokens inside a range.
5269void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5270 RangeComparisonResult compResult,
5271 SourceRange range) {
5272 while (MoreTokens()) {
5273 const unsigned I = NextToken();
5274 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005275 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5276 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005277
5278 SourceLocation TokLoc = GetTokenLoc(I);
5279 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005280 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005281 AdvanceToken();
5282 continue;
5283 }
5284 break;
5285 }
5286}
5287
5288/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005289/// \returns true if it advanced beyond all macro tokens, false otherwise.
5290bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005291 CXCursor updateC,
5292 RangeComparisonResult compResult,
5293 SourceRange range) {
5294 assert(MoreTokens());
5295 assert(isFunctionMacroToken(NextToken()) &&
5296 "Should be called only for macro arg tokens");
5297
5298 // This works differently than annotateAndAdvanceTokens; because expanded
5299 // macro arguments can have arbitrary translation-unit source order, we do not
5300 // advance the token index one by one until a token fails the range test.
5301 // We only advance once past all of the macro arg tokens if all of them
5302 // pass the range test. If one of them fails we keep the token index pointing
5303 // at the start of the macro arg tokens so that the failing token will be
5304 // annotated by a subsequent annotation try.
5305
5306 bool atLeastOneCompFail = false;
5307
5308 unsigned I = NextToken();
5309 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5310 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5311 if (TokLoc.isFileID())
5312 continue; // not macro arg token, it's parens or comma.
5313 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5314 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5315 Cursors[I] = updateC;
5316 } else
5317 atLeastOneCompFail = true;
5318 }
5319
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005320 if (atLeastOneCompFail)
5321 return false;
5322
5323 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5324 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005325}
5326
5327enum CXChildVisitResult
5328AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005329 SourceRange cursorRange = getRawCursorExtent(cursor);
5330 if (cursorRange.isInvalid())
5331 return CXChildVisit_Recurse;
5332
5333 if (!HasContextSensitiveKeywords) {
5334 // Objective-C properties can have context-sensitive keywords.
5335 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005336 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005337 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5338 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5339 }
5340 // Objective-C methods can have context-sensitive keywords.
5341 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5342 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005343 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005344 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5345 if (Method->getObjCDeclQualifier())
5346 HasContextSensitiveKeywords = true;
5347 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005348 for (const auto *P : Method->params()) {
5349 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005350 HasContextSensitiveKeywords = true;
5351 break;
5352 }
5353 }
5354 }
5355 }
5356 }
5357 // C++ methods can have context-sensitive keywords.
5358 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005359 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005360 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5361 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5362 HasContextSensitiveKeywords = true;
5363 }
5364 }
5365 // C++ classes can have context-sensitive keywords.
5366 else if (cursor.kind == CXCursor_StructDecl ||
5367 cursor.kind == CXCursor_ClassDecl ||
5368 cursor.kind == CXCursor_ClassTemplate ||
5369 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005370 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005371 if (D->hasAttr<FinalAttr>())
5372 HasContextSensitiveKeywords = true;
5373 }
5374 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005375
5376 // Don't override a property annotation with its getter/setter method.
5377 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5378 parent.kind == CXCursor_ObjCPropertyDecl)
5379 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005380
5381 if (clang_isPreprocessing(cursor.kind)) {
5382 // Items in the preprocessing record are kept separate from items in
5383 // declarations, so we keep a separate token index.
5384 unsigned SavedTokIdx = TokIdx;
5385 TokIdx = PreprocessingTokIdx;
5386
5387 // Skip tokens up until we catch up to the beginning of the preprocessing
5388 // entry.
5389 while (MoreTokens()) {
5390 const unsigned I = NextToken();
5391 SourceLocation TokLoc = GetTokenLoc(I);
5392 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5393 case RangeBefore:
5394 AdvanceToken();
5395 continue;
5396 case RangeAfter:
5397 case RangeOverlap:
5398 break;
5399 }
5400 break;
5401 }
5402
5403 // Look at all of the tokens within this range.
5404 while (MoreTokens()) {
5405 const unsigned I = NextToken();
5406 SourceLocation TokLoc = GetTokenLoc(I);
5407 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5408 case RangeBefore:
5409 llvm_unreachable("Infeasible");
5410 case RangeAfter:
5411 break;
5412 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005413 // For macro expansions, just note where the beginning of the macro
5414 // expansion occurs.
5415 if (cursor.kind == CXCursor_MacroExpansion) {
5416 if (TokLoc == cursorRange.getBegin())
5417 Cursors[I] = cursor;
5418 AdvanceToken();
5419 break;
5420 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005421 // We may have already annotated macro names inside macro definitions.
5422 if (Cursors[I].kind != CXCursor_MacroExpansion)
5423 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005424 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005425 continue;
5426 }
5427 break;
5428 }
5429
5430 // Save the preprocessing token index; restore the non-preprocessing
5431 // token index.
5432 PreprocessingTokIdx = TokIdx;
5433 TokIdx = SavedTokIdx;
5434 return CXChildVisit_Recurse;
5435 }
5436
5437 if (cursorRange.isInvalid())
5438 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005439
5440 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005441 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005442 const enum CXCursorKind K = clang_getCursorKind(parent);
5443 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005444 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5445 // Attributes are annotated out-of-order, skip tokens until we reach it.
5446 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005447 ? clang_getNullCursor() : parent;
5448
5449 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5450
5451 // Avoid having the cursor of an expression "overwrite" the annotation of the
5452 // variable declaration that it belongs to.
5453 // This can happen for C++ constructor expressions whose range generally
5454 // include the variable declaration, e.g.:
5455 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005456 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005457 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005458 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005459 const unsigned I = NextToken();
5460 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5461 E->getLocStart() == D->getLocation() &&
5462 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005463 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005464 AdvanceToken();
5465 }
5466 }
5467 }
5468
5469 // Before recursing into the children keep some state that we are going
5470 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5471 // extra work after the child nodes are visited.
5472 // Note that we don't call VisitChildren here to avoid traversing statements
5473 // code-recursively which can blow the stack.
5474
5475 PostChildrenInfo Info;
5476 Info.Cursor = cursor;
5477 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005478 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005479 Info.BeforeChildrenTokenIdx = NextToken();
5480 PostChildrenInfos.push_back(Info);
5481
5482 return CXChildVisit_Recurse;
5483}
5484
5485bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5486 if (PostChildrenInfos.empty())
5487 return false;
5488 const PostChildrenInfo &Info = PostChildrenInfos.back();
5489 if (!clang_equalCursors(Info.Cursor, cursor))
5490 return false;
5491
5492 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5493 const unsigned AfterChildren = NextToken();
5494 SourceRange cursorRange = Info.CursorRange;
5495
5496 // Scan the tokens that are at the end of the cursor, but are not captured
5497 // but the child cursors.
5498 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5499
5500 // Scan the tokens that are at the beginning of the cursor, but are not
5501 // capture by the child cursors.
5502 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5503 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5504 break;
5505
5506 Cursors[I] = cursor;
5507 }
5508
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005509 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5510 // encountered the attribute cursor.
5511 if (clang_isAttribute(cursor.kind))
5512 TokIdx = Info.BeforeReachingCursorIdx;
5513
Guy Benyei11169dd2012-12-18 14:30:41 +00005514 PostChildrenInfos.pop_back();
5515 return false;
5516}
5517
5518static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5519 CXCursor parent,
5520 CXClientData client_data) {
5521 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5522}
5523
5524static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5525 CXClientData client_data) {
5526 return static_cast<AnnotateTokensWorker*>(client_data)->
5527 postVisitChildren(cursor);
5528}
5529
5530namespace {
5531
5532/// \brief Uses the macro expansions in the preprocessing record to find
5533/// and mark tokens that are macro arguments. This info is used by the
5534/// AnnotateTokensWorker.
5535class MarkMacroArgTokensVisitor {
5536 SourceManager &SM;
5537 CXToken *Tokens;
5538 unsigned NumTokens;
5539 unsigned CurIdx;
5540
5541public:
5542 MarkMacroArgTokensVisitor(SourceManager &SM,
5543 CXToken *tokens, unsigned numTokens)
5544 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5545
5546 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5547 if (cursor.kind != CXCursor_MacroExpansion)
5548 return CXChildVisit_Continue;
5549
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005550 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005551 if (macroRange.getBegin() == macroRange.getEnd())
5552 return CXChildVisit_Continue; // it's not a function macro.
5553
5554 for (; CurIdx < NumTokens; ++CurIdx) {
5555 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5556 macroRange.getBegin()))
5557 break;
5558 }
5559
5560 if (CurIdx == NumTokens)
5561 return CXChildVisit_Break;
5562
5563 for (; CurIdx < NumTokens; ++CurIdx) {
5564 SourceLocation tokLoc = getTokenLoc(CurIdx);
5565 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5566 break;
5567
5568 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5569 }
5570
5571 if (CurIdx == NumTokens)
5572 return CXChildVisit_Break;
5573
5574 return CXChildVisit_Continue;
5575 }
5576
5577private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005578 CXToken &getTok(unsigned Idx) {
5579 assert(Idx < NumTokens);
5580 return Tokens[Idx];
5581 }
5582 const CXToken &getTok(unsigned Idx) const {
5583 assert(Idx < NumTokens);
5584 return Tokens[Idx];
5585 }
5586
Guy Benyei11169dd2012-12-18 14:30:41 +00005587 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005588 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005589 }
5590
5591 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5592 // The third field is reserved and currently not used. Use it here
5593 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005594 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005595 }
5596};
5597
5598} // end anonymous namespace
5599
5600static CXChildVisitResult
5601MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5602 CXClientData client_data) {
5603 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5604 parent);
5605}
5606
5607namespace {
5608 struct clang_annotateTokens_Data {
5609 CXTranslationUnit TU;
5610 ASTUnit *CXXUnit;
5611 CXToken *Tokens;
5612 unsigned NumTokens;
5613 CXCursor *Cursors;
5614 };
5615}
5616
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005617/// \brief Used by \c annotatePreprocessorTokens.
5618/// \returns true if lexing was finished, false otherwise.
5619static bool lexNext(Lexer &Lex, Token &Tok,
5620 unsigned &NextIdx, unsigned NumTokens) {
5621 if (NextIdx >= NumTokens)
5622 return true;
5623
5624 ++NextIdx;
5625 Lex.LexFromRawLexer(Tok);
5626 if (Tok.is(tok::eof))
5627 return true;
5628
5629 return false;
5630}
5631
Guy Benyei11169dd2012-12-18 14:30:41 +00005632static void annotatePreprocessorTokens(CXTranslationUnit TU,
5633 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005634 CXCursor *Cursors,
5635 CXToken *Tokens,
5636 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005637 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005638
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005639 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005640 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5641 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005642 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005643 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005644 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005645
5646 if (BeginLocInfo.first != EndLocInfo.first)
5647 return;
5648
5649 StringRef Buffer;
5650 bool Invalid = false;
5651 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5652 if (Buffer.empty() || Invalid)
5653 return;
5654
5655 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5656 CXXUnit->getASTContext().getLangOpts(),
5657 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5658 Buffer.end());
5659 Lex.SetCommentRetentionState(true);
5660
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005661 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005662 // Lex tokens in raw mode until we hit the end of the range, to avoid
5663 // entering #includes or expanding macros.
5664 while (true) {
5665 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005666 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5667 break;
5668 unsigned TokIdx = NextIdx-1;
5669 assert(Tok.getLocation() ==
5670 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005671
5672 reprocess:
5673 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005674 // We have found a preprocessing directive. Annotate the tokens
5675 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005676 //
5677 // FIXME: Some simple tests here could identify macro definitions and
5678 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005679
5680 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005681 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5682 break;
5683
5684 MacroInfo *MI = 0;
5685 if (Tok.is(tok::raw_identifier) &&
5686 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5687 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5688 break;
5689
5690 if (Tok.is(tok::raw_identifier)) {
5691 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5692 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5693 SourceLocation MappedTokLoc =
5694 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5695 MI = getMacroInfo(II, MappedTokLoc, TU);
5696 }
5697 }
5698
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005699 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005700 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005701 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5702 finished = true;
5703 break;
5704 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005705 // If we are in a macro definition, check if the token was ever a
5706 // macro name and annotate it if that's the case.
5707 if (MI) {
5708 SourceLocation SaveLoc = Tok.getLocation();
5709 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5710 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5711 Tok.setLocation(SaveLoc);
5712 if (MacroDef)
5713 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5714 Tok.getLocation(), TU);
5715 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005716 } while (!Tok.isAtStartOfLine());
5717
5718 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5719 assert(TokIdx <= LastIdx);
5720 SourceLocation EndLoc =
5721 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5722 CXCursor Cursor =
5723 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5724
5725 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005726 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005727
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005728 if (finished)
5729 break;
5730 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005731 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005732 }
5733}
5734
5735// This gets run a separate thread to avoid stack blowout.
5736static void clang_annotateTokensImpl(void *UserData) {
5737 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5738 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5739 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5740 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5741 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5742
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005743 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005744 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5745 setThreadBackgroundPriority();
5746
5747 // Determine the region of interest, which contains all of the tokens.
5748 SourceRange RegionOfInterest;
5749 RegionOfInterest.setBegin(
5750 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5751 RegionOfInterest.setEnd(
5752 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5753 Tokens[NumTokens-1])));
5754
Guy Benyei11169dd2012-12-18 14:30:41 +00005755 // Relex the tokens within the source range to look for preprocessing
5756 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005757 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005758
5759 // If begin location points inside a macro argument, set it to the expansion
5760 // location so we can have the full context when annotating semantically.
5761 {
5762 SourceManager &SM = CXXUnit->getSourceManager();
5763 SourceLocation Loc =
5764 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5765 if (Loc.isMacroID())
5766 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5767 }
5768
Guy Benyei11169dd2012-12-18 14:30:41 +00005769 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5770 // Search and mark tokens that are macro argument expansions.
5771 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5772 Tokens, NumTokens);
5773 CursorVisitor MacroArgMarker(TU,
5774 MarkMacroArgTokensVisitorDelegate, &Visitor,
5775 /*VisitPreprocessorLast=*/true,
5776 /*VisitIncludedEntities=*/false,
5777 RegionOfInterest);
5778 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5779 }
5780
5781 // Annotate all of the source locations in the region of interest that map to
5782 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005783 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005784
5785 // FIXME: We use a ridiculous stack size here because the data-recursion
5786 // algorithm uses a large stack frame than the non-data recursive version,
5787 // and AnnotationTokensWorker currently transforms the data-recursion
5788 // algorithm back into a traditional recursion by explicitly calling
5789 // VisitChildren(). We will need to remove this explicit recursive call.
5790 W.AnnotateTokens();
5791
5792 // If we ran into any entities that involve context-sensitive keywords,
5793 // take another pass through the tokens to mark them as such.
5794 if (W.hasContextSensitiveKeywords()) {
5795 for (unsigned I = 0; I != NumTokens; ++I) {
5796 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5797 continue;
5798
5799 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5800 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005801 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005802 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5803 if (Property->getPropertyAttributesAsWritten() != 0 &&
5804 llvm::StringSwitch<bool>(II->getName())
5805 .Case("readonly", true)
5806 .Case("assign", true)
5807 .Case("unsafe_unretained", true)
5808 .Case("readwrite", true)
5809 .Case("retain", true)
5810 .Case("copy", true)
5811 .Case("nonatomic", true)
5812 .Case("atomic", true)
5813 .Case("getter", true)
5814 .Case("setter", true)
5815 .Case("strong", true)
5816 .Case("weak", true)
5817 .Default(false))
5818 Tokens[I].int_data[0] = CXToken_Keyword;
5819 }
5820 continue;
5821 }
5822
5823 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5824 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5825 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5826 if (llvm::StringSwitch<bool>(II->getName())
5827 .Case("in", true)
5828 .Case("out", true)
5829 .Case("inout", true)
5830 .Case("oneway", true)
5831 .Case("bycopy", true)
5832 .Case("byref", true)
5833 .Default(false))
5834 Tokens[I].int_data[0] = CXToken_Keyword;
5835 continue;
5836 }
5837
5838 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5839 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5840 Tokens[I].int_data[0] = CXToken_Keyword;
5841 continue;
5842 }
5843 }
5844 }
5845}
5846
5847extern "C" {
5848
5849void clang_annotateTokens(CXTranslationUnit TU,
5850 CXToken *Tokens, unsigned NumTokens,
5851 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005852 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005853 LOG_BAD_TU(TU);
5854 return;
5855 }
5856 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005857 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005858 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005859 }
5860
5861 LOG_FUNC_SECTION {
5862 *Log << TU << ' ';
5863 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5864 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5865 *Log << clang_getRange(bloc, eloc);
5866 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005867
5868 // Any token we don't specifically annotate will have a NULL cursor.
5869 CXCursor C = clang_getNullCursor();
5870 for (unsigned I = 0; I != NumTokens; ++I)
5871 Cursors[I] = C;
5872
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005873 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005874 if (!CXXUnit)
5875 return;
5876
5877 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5878
5879 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5880 llvm::CrashRecoveryContext CRC;
5881 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5882 GetSafetyThreadStackSize() * 2)) {
5883 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5884 }
5885}
5886
5887} // end: extern "C"
5888
5889//===----------------------------------------------------------------------===//
5890// Operations for querying linkage of a cursor.
5891//===----------------------------------------------------------------------===//
5892
5893extern "C" {
5894CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5895 if (!clang_isDeclaration(cursor.kind))
5896 return CXLinkage_Invalid;
5897
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005898 const Decl *D = cxcursor::getCursorDecl(cursor);
5899 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005900 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005901 case NoLinkage:
5902 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005903 case InternalLinkage: return CXLinkage_Internal;
5904 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5905 case ExternalLinkage: return CXLinkage_External;
5906 };
5907
5908 return CXLinkage_Invalid;
5909}
5910} // end: extern "C"
5911
5912//===----------------------------------------------------------------------===//
5913// Operations for querying language of a cursor.
5914//===----------------------------------------------------------------------===//
5915
5916static CXLanguageKind getDeclLanguage(const Decl *D) {
5917 if (!D)
5918 return CXLanguage_C;
5919
5920 switch (D->getKind()) {
5921 default:
5922 break;
5923 case Decl::ImplicitParam:
5924 case Decl::ObjCAtDefsField:
5925 case Decl::ObjCCategory:
5926 case Decl::ObjCCategoryImpl:
5927 case Decl::ObjCCompatibleAlias:
5928 case Decl::ObjCImplementation:
5929 case Decl::ObjCInterface:
5930 case Decl::ObjCIvar:
5931 case Decl::ObjCMethod:
5932 case Decl::ObjCProperty:
5933 case Decl::ObjCPropertyImpl:
5934 case Decl::ObjCProtocol:
5935 return CXLanguage_ObjC;
5936 case Decl::CXXConstructor:
5937 case Decl::CXXConversion:
5938 case Decl::CXXDestructor:
5939 case Decl::CXXMethod:
5940 case Decl::CXXRecord:
5941 case Decl::ClassTemplate:
5942 case Decl::ClassTemplatePartialSpecialization:
5943 case Decl::ClassTemplateSpecialization:
5944 case Decl::Friend:
5945 case Decl::FriendTemplate:
5946 case Decl::FunctionTemplate:
5947 case Decl::LinkageSpec:
5948 case Decl::Namespace:
5949 case Decl::NamespaceAlias:
5950 case Decl::NonTypeTemplateParm:
5951 case Decl::StaticAssert:
5952 case Decl::TemplateTemplateParm:
5953 case Decl::TemplateTypeParm:
5954 case Decl::UnresolvedUsingTypename:
5955 case Decl::UnresolvedUsingValue:
5956 case Decl::Using:
5957 case Decl::UsingDirective:
5958 case Decl::UsingShadow:
5959 return CXLanguage_CPlusPlus;
5960 }
5961
5962 return CXLanguage_C;
5963}
5964
5965extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005966
5967static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5968 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5969 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005970
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005971 switch (D->getAvailability()) {
5972 case AR_Available:
5973 case AR_NotYetIntroduced:
5974 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005975 return getCursorAvailabilityForDecl(
5976 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005977 return CXAvailability_Available;
5978
5979 case AR_Deprecated:
5980 return CXAvailability_Deprecated;
5981
5982 case AR_Unavailable:
5983 return CXAvailability_NotAvailable;
5984 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005985
5986 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005987}
5988
Guy Benyei11169dd2012-12-18 14:30:41 +00005989enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5990 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005991 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5992 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005993
5994 return CXAvailability_Available;
5995}
5996
5997static CXVersion convertVersion(VersionTuple In) {
5998 CXVersion Out = { -1, -1, -1 };
5999 if (In.empty())
6000 return Out;
6001
6002 Out.Major = In.getMajor();
6003
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006004 Optional<unsigned> Minor = In.getMinor();
6005 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006006 Out.Minor = *Minor;
6007 else
6008 return Out;
6009
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006010 Optional<unsigned> Subminor = In.getSubminor();
6011 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006012 Out.Subminor = *Subminor;
6013
6014 return Out;
6015}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006016
6017static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6018 int *always_deprecated,
6019 CXString *deprecated_message,
6020 int *always_unavailable,
6021 CXString *unavailable_message,
6022 CXPlatformAvailability *availability,
6023 int availability_size) {
6024 bool HadAvailAttr = false;
6025 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006026 for (auto A : D->attrs()) {
6027 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006028 HadAvailAttr = true;
6029 if (always_deprecated)
6030 *always_deprecated = 1;
6031 if (deprecated_message)
6032 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
6033 continue;
6034 }
6035
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006036 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006037 HadAvailAttr = true;
6038 if (always_unavailable)
6039 *always_unavailable = 1;
6040 if (unavailable_message) {
6041 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6042 }
6043 continue;
6044 }
6045
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006046 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006047 HadAvailAttr = true;
6048 if (N < availability_size) {
6049 availability[N].Platform
6050 = cxstring::createDup(Avail->getPlatform()->getName());
6051 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6052 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6053 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6054 availability[N].Unavailable = Avail->getUnavailable();
6055 availability[N].Message = cxstring::createDup(Avail->getMessage());
6056 }
6057 ++N;
6058 }
6059 }
6060
6061 if (!HadAvailAttr)
6062 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6063 return getCursorPlatformAvailabilityForDecl(
6064 cast<Decl>(EnumConst->getDeclContext()),
6065 always_deprecated,
6066 deprecated_message,
6067 always_unavailable,
6068 unavailable_message,
6069 availability,
6070 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006071
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006072 return N;
6073}
6074
Guy Benyei11169dd2012-12-18 14:30:41 +00006075int clang_getCursorPlatformAvailability(CXCursor cursor,
6076 int *always_deprecated,
6077 CXString *deprecated_message,
6078 int *always_unavailable,
6079 CXString *unavailable_message,
6080 CXPlatformAvailability *availability,
6081 int availability_size) {
6082 if (always_deprecated)
6083 *always_deprecated = 0;
6084 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006085 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006086 if (always_unavailable)
6087 *always_unavailable = 0;
6088 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006089 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006090
Guy Benyei11169dd2012-12-18 14:30:41 +00006091 if (!clang_isDeclaration(cursor.kind))
6092 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006093
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006094 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006095 if (!D)
6096 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006097
6098 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6099 deprecated_message,
6100 always_unavailable,
6101 unavailable_message,
6102 availability,
6103 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006104}
6105
6106void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6107 clang_disposeString(availability->Platform);
6108 clang_disposeString(availability->Message);
6109}
6110
6111CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6112 if (clang_isDeclaration(cursor.kind))
6113 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6114
6115 return CXLanguage_Invalid;
6116}
6117
6118 /// \brief If the given cursor is the "templated" declaration
6119 /// descibing a class or function template, return the class or
6120 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006121static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006122 if (!D)
6123 return 0;
6124
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006125 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006126 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6127 return FunTmpl;
6128
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006129 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006130 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6131 return ClassTmpl;
6132
6133 return D;
6134}
6135
6136CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6137 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006138 if (const Decl *D = getCursorDecl(cursor)) {
6139 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006140 if (!DC)
6141 return clang_getNullCursor();
6142
6143 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6144 getCursorTU(cursor));
6145 }
6146 }
6147
6148 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006149 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006150 return MakeCXCursor(D, getCursorTU(cursor));
6151 }
6152
6153 return clang_getNullCursor();
6154}
6155
6156CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6157 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006158 if (const Decl *D = getCursorDecl(cursor)) {
6159 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006160 if (!DC)
6161 return clang_getNullCursor();
6162
6163 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6164 getCursorTU(cursor));
6165 }
6166 }
6167
6168 // FIXME: Note that we can't easily compute the lexical context of a
6169 // statement or expression, so we return nothing.
6170 return clang_getNullCursor();
6171}
6172
6173CXFile clang_getIncludedFile(CXCursor cursor) {
6174 if (cursor.kind != CXCursor_InclusionDirective)
6175 return 0;
6176
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006177 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006178 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006179}
6180
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006181unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6182 if (C.kind != CXCursor_ObjCPropertyDecl)
6183 return CXObjCPropertyAttr_noattr;
6184
6185 unsigned Result = CXObjCPropertyAttr_noattr;
6186 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6187 ObjCPropertyDecl::PropertyAttributeKind Attr =
6188 PD->getPropertyAttributesAsWritten();
6189
6190#define SET_CXOBJCPROP_ATTR(A) \
6191 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6192 Result |= CXObjCPropertyAttr_##A
6193 SET_CXOBJCPROP_ATTR(readonly);
6194 SET_CXOBJCPROP_ATTR(getter);
6195 SET_CXOBJCPROP_ATTR(assign);
6196 SET_CXOBJCPROP_ATTR(readwrite);
6197 SET_CXOBJCPROP_ATTR(retain);
6198 SET_CXOBJCPROP_ATTR(copy);
6199 SET_CXOBJCPROP_ATTR(nonatomic);
6200 SET_CXOBJCPROP_ATTR(setter);
6201 SET_CXOBJCPROP_ATTR(atomic);
6202 SET_CXOBJCPROP_ATTR(weak);
6203 SET_CXOBJCPROP_ATTR(strong);
6204 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6205#undef SET_CXOBJCPROP_ATTR
6206
6207 return Result;
6208}
6209
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006210unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6211 if (!clang_isDeclaration(C.kind))
6212 return CXObjCDeclQualifier_None;
6213
6214 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6215 const Decl *D = getCursorDecl(C);
6216 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6217 QT = MD->getObjCDeclQualifier();
6218 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6219 QT = PD->getObjCDeclQualifier();
6220 if (QT == Decl::OBJC_TQ_None)
6221 return CXObjCDeclQualifier_None;
6222
6223 unsigned Result = CXObjCDeclQualifier_None;
6224 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6225 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6226 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6227 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6228 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6229 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6230
6231 return Result;
6232}
6233
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006234unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6235 if (!clang_isDeclaration(C.kind))
6236 return 0;
6237
6238 const Decl *D = getCursorDecl(C);
6239 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6240 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6241 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6242 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6243
6244 return 0;
6245}
6246
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006247unsigned clang_Cursor_isVariadic(CXCursor C) {
6248 if (!clang_isDeclaration(C.kind))
6249 return 0;
6250
6251 const Decl *D = getCursorDecl(C);
6252 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6253 return FD->isVariadic();
6254 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6255 return MD->isVariadic();
6256
6257 return 0;
6258}
6259
Guy Benyei11169dd2012-12-18 14:30:41 +00006260CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6261 if (!clang_isDeclaration(C.kind))
6262 return clang_getNullRange();
6263
6264 const Decl *D = getCursorDecl(C);
6265 ASTContext &Context = getCursorContext(C);
6266 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6267 if (!RC)
6268 return clang_getNullRange();
6269
6270 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6271}
6272
6273CXString clang_Cursor_getRawCommentText(CXCursor C) {
6274 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006275 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006276
6277 const Decl *D = getCursorDecl(C);
6278 ASTContext &Context = getCursorContext(C);
6279 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6280 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6281 StringRef();
6282
6283 // Don't duplicate the string because RawText points directly into source
6284 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006285 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006286}
6287
6288CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6289 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006290 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006291
6292 const Decl *D = getCursorDecl(C);
6293 const ASTContext &Context = getCursorContext(C);
6294 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6295
6296 if (RC) {
6297 StringRef BriefText = RC->getBriefText(Context);
6298
6299 // Don't duplicate the string because RawComment ensures that this memory
6300 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006301 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006302 }
6303
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006304 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006305}
6306
6307CXComment clang_Cursor_getParsedComment(CXCursor C) {
6308 if (!clang_isDeclaration(C.kind))
6309 return cxcomment::createCXComment(NULL, NULL);
6310
6311 const Decl *D = getCursorDecl(C);
6312 const ASTContext &Context = getCursorContext(C);
6313 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6314
6315 return cxcomment::createCXComment(FC, getCursorTU(C));
6316}
6317
6318CXModule clang_Cursor_getModule(CXCursor C) {
6319 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006320 if (const ImportDecl *ImportD =
6321 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006322 return ImportD->getImportedModule();
6323 }
6324
6325 return 0;
6326}
6327
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006328CXFile clang_Module_getASTFile(CXModule CXMod) {
6329 if (!CXMod)
6330 return 0;
6331 Module *Mod = static_cast<Module*>(CXMod);
6332 return const_cast<FileEntry *>(Mod->getASTFile());
6333}
6334
Guy Benyei11169dd2012-12-18 14:30:41 +00006335CXModule clang_Module_getParent(CXModule CXMod) {
6336 if (!CXMod)
6337 return 0;
6338 Module *Mod = static_cast<Module*>(CXMod);
6339 return Mod->Parent;
6340}
6341
6342CXString clang_Module_getName(CXModule CXMod) {
6343 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006344 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006345 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006346 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006347}
6348
6349CXString clang_Module_getFullName(CXModule CXMod) {
6350 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006351 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006352 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006353 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006354}
6355
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006356unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6357 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006358 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006359 LOG_BAD_TU(TU);
6360 return 0;
6361 }
6362 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006363 return 0;
6364 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006365 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6366 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6367 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006368}
6369
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006370CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6371 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006372 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006373 LOG_BAD_TU(TU);
6374 return 0;
6375 }
6376 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006377 return 0;
6378 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006379 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006380
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006381 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6382 if (Index < TopHeaders.size())
6383 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006384
6385 return 0;
6386}
6387
6388} // end: extern "C"
6389
6390//===----------------------------------------------------------------------===//
6391// C++ AST instrospection.
6392//===----------------------------------------------------------------------===//
6393
6394extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006395unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6396 if (!clang_isDeclaration(C.kind))
6397 return 0;
6398
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006399 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006400 const CXXMethodDecl *Method =
6401 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006402 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6403}
6404
Guy Benyei11169dd2012-12-18 14:30:41 +00006405unsigned clang_CXXMethod_isStatic(CXCursor C) {
6406 if (!clang_isDeclaration(C.kind))
6407 return 0;
6408
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006409 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006410 const CXXMethodDecl *Method =
6411 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006412 return (Method && Method->isStatic()) ? 1 : 0;
6413}
6414
6415unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6416 if (!clang_isDeclaration(C.kind))
6417 return 0;
6418
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006419 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006420 const CXXMethodDecl *Method =
6421 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006422 return (Method && Method->isVirtual()) ? 1 : 0;
6423}
6424} // end: extern "C"
6425
6426//===----------------------------------------------------------------------===//
6427// Attribute introspection.
6428//===----------------------------------------------------------------------===//
6429
6430extern "C" {
6431CXType clang_getIBOutletCollectionType(CXCursor C) {
6432 if (C.kind != CXCursor_IBOutletCollectionAttr)
6433 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6434
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006435 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006436 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6437
6438 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6439}
6440} // end: extern "C"
6441
6442//===----------------------------------------------------------------------===//
6443// Inspecting memory usage.
6444//===----------------------------------------------------------------------===//
6445
6446typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6447
6448static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6449 enum CXTUResourceUsageKind k,
6450 unsigned long amount) {
6451 CXTUResourceUsageEntry entry = { k, amount };
6452 entries.push_back(entry);
6453}
6454
6455extern "C" {
6456
6457const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6458 const char *str = "";
6459 switch (kind) {
6460 case CXTUResourceUsage_AST:
6461 str = "ASTContext: expressions, declarations, and types";
6462 break;
6463 case CXTUResourceUsage_Identifiers:
6464 str = "ASTContext: identifiers";
6465 break;
6466 case CXTUResourceUsage_Selectors:
6467 str = "ASTContext: selectors";
6468 break;
6469 case CXTUResourceUsage_GlobalCompletionResults:
6470 str = "Code completion: cached global results";
6471 break;
6472 case CXTUResourceUsage_SourceManagerContentCache:
6473 str = "SourceManager: content cache allocator";
6474 break;
6475 case CXTUResourceUsage_AST_SideTables:
6476 str = "ASTContext: side tables";
6477 break;
6478 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6479 str = "SourceManager: malloc'ed memory buffers";
6480 break;
6481 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6482 str = "SourceManager: mmap'ed memory buffers";
6483 break;
6484 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6485 str = "ExternalASTSource: malloc'ed memory buffers";
6486 break;
6487 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6488 str = "ExternalASTSource: mmap'ed memory buffers";
6489 break;
6490 case CXTUResourceUsage_Preprocessor:
6491 str = "Preprocessor: malloc'ed memory";
6492 break;
6493 case CXTUResourceUsage_PreprocessingRecord:
6494 str = "Preprocessor: PreprocessingRecord";
6495 break;
6496 case CXTUResourceUsage_SourceManager_DataStructures:
6497 str = "SourceManager: data structures and tables";
6498 break;
6499 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6500 str = "Preprocessor: header search tables";
6501 break;
6502 }
6503 return str;
6504}
6505
6506CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006507 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006508 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006509 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6510 return usage;
6511 }
6512
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006513 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006514 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006515 ASTContext &astContext = astUnit->getASTContext();
6516
6517 // How much memory is used by AST nodes and types?
6518 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6519 (unsigned long) astContext.getASTAllocatedMemory());
6520
6521 // How much memory is used by identifiers?
6522 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6523 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6524
6525 // How much memory is used for selectors?
6526 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6527 (unsigned long) astContext.Selectors.getTotalMemory());
6528
6529 // How much memory is used by ASTContext's side tables?
6530 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6531 (unsigned long) astContext.getSideTableAllocatedMemory());
6532
6533 // How much memory is used for caching global code completion results?
6534 unsigned long completionBytes = 0;
6535 if (GlobalCodeCompletionAllocator *completionAllocator =
6536 astUnit->getCachedCompletionAllocator().getPtr()) {
6537 completionBytes = completionAllocator->getTotalMemory();
6538 }
6539 createCXTUResourceUsageEntry(*entries,
6540 CXTUResourceUsage_GlobalCompletionResults,
6541 completionBytes);
6542
6543 // How much memory is being used by SourceManager's content cache?
6544 createCXTUResourceUsageEntry(*entries,
6545 CXTUResourceUsage_SourceManagerContentCache,
6546 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6547
6548 // How much memory is being used by the MemoryBuffer's in SourceManager?
6549 const SourceManager::MemoryBufferSizes &srcBufs =
6550 astUnit->getSourceManager().getMemoryBufferSizes();
6551
6552 createCXTUResourceUsageEntry(*entries,
6553 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6554 (unsigned long) srcBufs.malloc_bytes);
6555 createCXTUResourceUsageEntry(*entries,
6556 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6557 (unsigned long) srcBufs.mmap_bytes);
6558 createCXTUResourceUsageEntry(*entries,
6559 CXTUResourceUsage_SourceManager_DataStructures,
6560 (unsigned long) astContext.getSourceManager()
6561 .getDataStructureSizes());
6562
6563 // How much memory is being used by the ExternalASTSource?
6564 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6565 const ExternalASTSource::MemoryBufferSizes &sizes =
6566 esrc->getMemoryBufferSizes();
6567
6568 createCXTUResourceUsageEntry(*entries,
6569 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6570 (unsigned long) sizes.malloc_bytes);
6571 createCXTUResourceUsageEntry(*entries,
6572 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6573 (unsigned long) sizes.mmap_bytes);
6574 }
6575
6576 // How much memory is being used by the Preprocessor?
6577 Preprocessor &pp = astUnit->getPreprocessor();
6578 createCXTUResourceUsageEntry(*entries,
6579 CXTUResourceUsage_Preprocessor,
6580 pp.getTotalMemory());
6581
6582 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6583 createCXTUResourceUsageEntry(*entries,
6584 CXTUResourceUsage_PreprocessingRecord,
6585 pRec->getTotalMemory());
6586 }
6587
6588 createCXTUResourceUsageEntry(*entries,
6589 CXTUResourceUsage_Preprocessor_HeaderSearch,
6590 pp.getHeaderSearchInfo().getTotalMemory());
6591
6592 CXTUResourceUsage usage = { (void*) entries.get(),
6593 (unsigned) entries->size(),
6594 entries->size() ? &(*entries)[0] : 0 };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006595 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006596 return usage;
6597}
6598
6599void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6600 if (usage.data)
6601 delete (MemUsageEntries*) usage.data;
6602}
6603
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006604CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6605 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006606 skipped->count = 0;
6607 skipped->ranges = 0;
6608
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006609 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006610 LOG_BAD_TU(TU);
6611 return skipped;
6612 }
6613
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006614 if (!file)
6615 return skipped;
6616
6617 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6618 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6619 if (!ppRec)
6620 return skipped;
6621
6622 ASTContext &Ctx = astUnit->getASTContext();
6623 SourceManager &sm = Ctx.getSourceManager();
6624 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6625 FileID wantedFileID = sm.translateFile(fileEntry);
6626
6627 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6628 std::vector<SourceRange> wantedRanges;
6629 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6630 i != ei; ++i) {
6631 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6632 wantedRanges.push_back(*i);
6633 }
6634
6635 skipped->count = wantedRanges.size();
6636 skipped->ranges = new CXSourceRange[skipped->count];
6637 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6638 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6639
6640 return skipped;
6641}
6642
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006643void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6644 if (ranges) {
6645 delete[] ranges->ranges;
6646 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006647 }
6648}
6649
Guy Benyei11169dd2012-12-18 14:30:41 +00006650} // end extern "C"
6651
6652void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6653 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6654 for (unsigned I = 0; I != Usage.numEntries; ++I)
6655 fprintf(stderr, " %s: %lu\n",
6656 clang_getTUResourceUsageName(Usage.entries[I].kind),
6657 Usage.entries[I].amount);
6658
6659 clang_disposeCXTUResourceUsage(Usage);
6660}
6661
6662//===----------------------------------------------------------------------===//
6663// Misc. utility functions.
6664//===----------------------------------------------------------------------===//
6665
6666/// Default to using an 8 MB stack size on "safety" threads.
6667static unsigned SafetyStackThreadSize = 8 << 20;
6668
6669namespace clang {
6670
6671bool RunSafely(llvm::CrashRecoveryContext &CRC,
6672 void (*Fn)(void*), void *UserData,
6673 unsigned Size) {
6674 if (!Size)
6675 Size = GetSafetyThreadStackSize();
6676 if (Size)
6677 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6678 return CRC.RunSafely(Fn, UserData);
6679}
6680
6681unsigned GetSafetyThreadStackSize() {
6682 return SafetyStackThreadSize;
6683}
6684
6685void SetSafetyThreadStackSize(unsigned Value) {
6686 SafetyStackThreadSize = Value;
6687}
6688
6689}
6690
6691void clang::setThreadBackgroundPriority() {
6692 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6693 return;
6694
6695 // FIXME: Move to llvm/Support and make it cross-platform.
6696#ifdef __APPLE__
6697 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6698#endif
6699}
6700
6701void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6702 if (!Unit)
6703 return;
6704
6705 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6706 DEnd = Unit->stored_diag_end();
6707 D != DEnd; ++D) {
6708 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6709 CXString Msg = clang_formatDiagnostic(&Diag,
6710 clang_defaultDiagnosticDisplayOptions());
6711 fprintf(stderr, "%s\n", clang_getCString(Msg));
6712 clang_disposeString(Msg);
6713 }
6714#ifdef LLVM_ON_WIN32
6715 // On Windows, force a flush, since there may be multiple copies of
6716 // stderr and stdout in the file system, all with different buffers
6717 // but writing to the same device.
6718 fflush(stderr);
6719#endif
6720}
6721
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006722MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6723 SourceLocation MacroDefLoc,
6724 CXTranslationUnit TU){
6725 if (MacroDefLoc.isInvalid() || !TU)
6726 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006727 if (!II.hadMacroDefinition())
6728 return 0;
6729
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006730 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006731 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006732 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006733 if (MD) {
6734 for (MacroDirective::DefInfo
6735 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6736 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6737 return Def.getMacroInfo();
6738 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006739 }
6740
6741 return 0;
6742}
6743
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006744const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6745 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006746 if (!MacroDef || !TU)
6747 return 0;
6748 const IdentifierInfo *II = MacroDef->getName();
6749 if (!II)
6750 return 0;
6751
6752 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6753}
6754
6755MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6756 const Token &Tok,
6757 CXTranslationUnit TU) {
6758 if (!MI || !TU)
6759 return 0;
6760 if (Tok.isNot(tok::raw_identifier))
6761 return 0;
6762
6763 if (MI->getNumTokens() == 0)
6764 return 0;
6765 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6766 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006767 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006768
6769 // Check that the token is inside the definition and not its argument list.
6770 SourceManager &SM = Unit->getSourceManager();
6771 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6772 return 0;
6773 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6774 return 0;
6775
6776 Preprocessor &PP = Unit->getPreprocessor();
6777 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6778 if (!PPRec)
6779 return 0;
6780
6781 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6782 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6783 if (!II.hadMacroDefinition())
6784 return 0;
6785
6786 // Check that the identifier is not one of the macro arguments.
6787 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6788 return 0;
6789
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006790 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6791 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006792 return 0;
6793
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006794 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006795}
6796
6797MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6798 SourceLocation Loc,
6799 CXTranslationUnit TU) {
6800 if (Loc.isInvalid() || !MI || !TU)
6801 return 0;
6802
6803 if (MI->getNumTokens() == 0)
6804 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006805 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006806 Preprocessor &PP = Unit->getPreprocessor();
6807 if (!PP.getPreprocessingRecord())
6808 return 0;
6809 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6810 Token Tok;
6811 if (PP.getRawToken(Loc, Tok))
6812 return 0;
6813
6814 return checkForMacroInMacroDefinition(MI, Tok, TU);
6815}
6816
Guy Benyei11169dd2012-12-18 14:30:41 +00006817extern "C" {
6818
6819CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006820 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006821}
6822
6823} // end: extern "C"
6824
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006825Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6826 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006827 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006828 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006829 if (Unit->isMainFileAST())
6830 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006831 return *this;
6832 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006833 } else {
6834 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006835 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006836 return *this;
6837}
6838
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006839Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6840 *this << FE->getName();
6841 return *this;
6842}
6843
6844Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6845 CXString cursorName = clang_getCursorDisplayName(cursor);
6846 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6847 clang_disposeString(cursorName);
6848 return *this;
6849}
6850
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006851Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6852 CXFile File;
6853 unsigned Line, Column;
6854 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6855 CXString FileName = clang_getFileName(File);
6856 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6857 clang_disposeString(FileName);
6858 return *this;
6859}
6860
6861Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6862 CXSourceLocation BLoc = clang_getRangeStart(range);
6863 CXSourceLocation ELoc = clang_getRangeEnd(range);
6864
6865 CXFile BFile;
6866 unsigned BLine, BColumn;
6867 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6868
6869 CXFile EFile;
6870 unsigned ELine, EColumn;
6871 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6872
6873 CXString BFileName = clang_getFileName(BFile);
6874 if (BFile == EFile) {
6875 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6876 BLine, BColumn, ELine, EColumn);
6877 } else {
6878 CXString EFileName = clang_getFileName(EFile);
6879 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6880 BLine, BColumn)
6881 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6882 ELine, EColumn);
6883 clang_disposeString(EFileName);
6884 }
6885 clang_disposeString(BFileName);
6886 return *this;
6887}
6888
6889Logger &cxindex::Logger::operator<<(CXString Str) {
6890 *this << clang_getCString(Str);
6891 return *this;
6892}
6893
6894Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6895 LogOS << Fmt;
6896 return *this;
6897}
6898
6899cxindex::Logger::~Logger() {
6900 LogOS.flush();
6901
6902 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6903
6904 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6905
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006906 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006907 OS << "[libclang:" << Name << ':';
6908
6909 // FIXME: Portability.
6910#if HAVE_PTHREAD_H && __APPLE__
6911 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6912 OS << tid << ':';
6913#endif
6914
6915 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6916 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6917 OS << Msg.str() << '\n';
6918
6919 if (Trace) {
6920 llvm::sys::PrintStackTrace(stderr);
6921 OS << "--------------------------------------------------\n";
6922 }
6923}