blob: 614bb0cbfc97b8fb0201b99d28fde9fd364ff530 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXComment.h"
19#include "CXCursor.h"
20#include "CXSourceLocation.h"
21#include "CXString.h"
22#include "CXTranslationUnit.h"
23#include "CXType.h"
24#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000025#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000030#include "clang/Basic/Version.h"
31#include "clang/Frontend/ASTUnit.h"
32#include "clang/Frontend/CompilerInstance.h"
33#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000034#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000035#include "clang/Lex/HeaderSearch.h"
36#include "clang/Lex/Lexer.h"
37#include "clang/Lex/PreprocessingRecord.h"
38#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000039#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000040#include "llvm/ADT/Optional.h"
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/StringSwitch.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000043#include "llvm/Config/config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000044#include "llvm/Support/Compiler.h"
45#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000046#include "llvm/Support/Format.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/MemoryBuffer.h"
48#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000049#include "llvm/Support/Program.h"
50#include "llvm/Support/SaveAndRestore.h"
51#include "llvm/Support/Signals.h"
52#include "llvm/Support/Threading.h"
53#include "llvm/Support/Timer.h"
54#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000055
56#if HAVE_PTHREAD_H
57#include <pthread.h>
58#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000059
60using namespace clang;
61using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000062using namespace clang::cxtu;
63using namespace clang::cxindex;
64
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000065CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
66 if (!AU)
Guy Benyei11169dd2012-12-18 14:30:41 +000067 return 0;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000068 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000069 CXTranslationUnit D = new CXTranslationUnitImpl();
70 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000071 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000072 D->StringPool = new cxstring::CXStringPool();
Guy Benyei11169dd2012-12-18 14:30:41 +000073 D->Diagnostics = 0;
74 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Dmitri Gribenko9e605112013-11-13 22:16:51 +000075 D->CommentToXML = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +000076 return D;
77}
78
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000079bool cxtu::isASTReadError(ASTUnit *AU) {
80 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
81 DEnd = AU->stored_diag_end();
82 D != DEnd; ++D) {
83 if (D->getLevel() >= DiagnosticsEngine::Error &&
84 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
85 diag::DiagCat_AST_Deserialization_Issue)
86 return true;
87 }
88 return false;
89}
90
Guy Benyei11169dd2012-12-18 14:30:41 +000091cxtu::CXTUOwner::~CXTUOwner() {
92 if (TU)
93 clang_disposeTranslationUnit(TU);
94}
95
96/// \brief Compare two source ranges to determine their relative position in
97/// the translation unit.
98static RangeComparisonResult RangeCompare(SourceManager &SM,
99 SourceRange R1,
100 SourceRange R2) {
101 assert(R1.isValid() && "First range is invalid?");
102 assert(R2.isValid() && "Second range is invalid?");
103 if (R1.getEnd() != R2.getBegin() &&
104 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
105 return RangeBefore;
106 if (R2.getEnd() != R1.getBegin() &&
107 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
108 return RangeAfter;
109 return RangeOverlap;
110}
111
112/// \brief Determine if a source location falls within, before, or after a
113/// a given source range.
114static RangeComparisonResult LocationCompare(SourceManager &SM,
115 SourceLocation L, SourceRange R) {
116 assert(R.isValid() && "First range is invalid?");
117 assert(L.isValid() && "Second range is invalid?");
118 if (L == R.getBegin() || L == R.getEnd())
119 return RangeOverlap;
120 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
121 return RangeBefore;
122 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
123 return RangeAfter;
124 return RangeOverlap;
125}
126
127/// \brief Translate a Clang source range into a CIndex source range.
128///
129/// Clang internally represents ranges where the end location points to the
130/// start of the token at the end. However, for external clients it is more
131/// useful to have a CXSourceRange be a proper half-open interval. This routine
132/// does the appropriate translation.
133CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
134 const LangOptions &LangOpts,
135 const CharSourceRange &R) {
136 // We want the last character in this location, so we will adjust the
137 // location accordingly.
138 SourceLocation EndLoc = R.getEnd();
139 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
140 EndLoc = SM.getExpansionRange(EndLoc).second;
141 if (R.isTokenRange() && !EndLoc.isInvalid()) {
142 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
143 SM, LangOpts);
144 EndLoc = EndLoc.getLocWithOffset(Length);
145 }
146
Bill Wendlingeade3622013-01-23 08:25:41 +0000147 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000148 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000149 R.getBegin().getRawEncoding(),
150 EndLoc.getRawEncoding()
151 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000152 return Result;
153}
154
155//===----------------------------------------------------------------------===//
156// Cursor visitor.
157//===----------------------------------------------------------------------===//
158
159static SourceRange getRawCursorExtent(CXCursor C);
160static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
161
162
163RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
164 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
165}
166
167/// \brief Visit the given cursor and, if requested by the visitor,
168/// its children.
169///
170/// \param Cursor the cursor to visit.
171///
172/// \param CheckedRegionOfInterest if true, then the caller already checked
173/// that this cursor is within the region of interest.
174///
175/// \returns true if the visitation should be aborted, false if it
176/// should continue.
177bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
178 if (clang_isInvalid(Cursor.kind))
179 return false;
180
181 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000182 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000183 if (!D) {
184 assert(0 && "Invalid declaration cursor");
185 return true; // abort.
186 }
187
188 // Ignore implicit declarations, unless it's an objc method because
189 // currently we should report implicit methods for properties when indexing.
190 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
191 return false;
192 }
193
194 // If we have a range of interest, and this cursor doesn't intersect with it,
195 // we're done.
196 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
197 SourceRange Range = getRawCursorExtent(Cursor);
198 if (Range.isInvalid() || CompareRegionOfInterest(Range))
199 return false;
200 }
201
202 switch (Visitor(Cursor, Parent, ClientData)) {
203 case CXChildVisit_Break:
204 return true;
205
206 case CXChildVisit_Continue:
207 return false;
208
209 case CXChildVisit_Recurse: {
210 bool ret = VisitChildren(Cursor);
211 if (PostChildrenVisitor)
212 if (PostChildrenVisitor(Cursor, ClientData))
213 return true;
214 return ret;
215 }
216 }
217
218 llvm_unreachable("Invalid CXChildVisitResult!");
219}
220
221static bool visitPreprocessedEntitiesInRange(SourceRange R,
222 PreprocessingRecord &PPRec,
223 CursorVisitor &Visitor) {
224 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
225 FileID FID;
226
227 if (!Visitor.shouldVisitIncludedEntities()) {
228 // If the begin/end of the range lie in the same FileID, do the optimization
229 // where we skip preprocessed entities that do not come from the same FileID.
230 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
231 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
232 FID = FileID();
233 }
234
235 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
236 Entities = PPRec.getPreprocessedEntitiesInRange(R);
237 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
238 PPRec, FID);
239}
240
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000241bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000242 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000243 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000244
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000245 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 SourceManager &SM = Unit->getSourceManager();
247
248 std::pair<FileID, unsigned>
249 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
250 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
251
252 if (End.first != Begin.first) {
253 // If the end does not reside in the same file, try to recover by
254 // picking the end of the file of begin location.
255 End.first = Begin.first;
256 End.second = SM.getFileIDSize(Begin.first);
257 }
258
259 assert(Begin.first == End.first);
260 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000261 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000262
263 FileID File = Begin.first;
264 unsigned Offset = Begin.second;
265 unsigned Length = End.second - Begin.second;
266
267 if (!VisitDeclsOnly && !VisitPreprocessorLast)
268 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000271 if (visitDeclsFromFileRegion(File, Offset, Length))
272 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000273
274 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000275 return visitPreprocessedEntitiesInRegion();
276
277 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000278}
279
280static bool isInLexicalContext(Decl *D, DeclContext *DC) {
281 if (!DC)
282 return false;
283
284 for (DeclContext *DeclDC = D->getLexicalDeclContext();
285 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
286 if (DeclDC == DC)
287 return true;
288 }
289 return false;
290}
291
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000292bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000293 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000294 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000295 SourceManager &SM = Unit->getSourceManager();
296 SourceRange Range = RegionOfInterest;
297
298 SmallVector<Decl *, 16> Decls;
299 Unit->findFileRegionDecls(File, Offset, Length, Decls);
300
301 // If we didn't find any file level decls for the file, try looking at the
302 // file that it was included from.
303 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
304 bool Invalid = false;
305 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
306 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000307 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000308
309 SourceLocation Outer;
310 if (SLEntry.isFile())
311 Outer = SLEntry.getFile().getIncludeLoc();
312 else
313 Outer = SLEntry.getExpansion().getExpansionLocStart();
314 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000317 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000318 Length = 0;
319 Unit->findFileRegionDecls(File, Offset, Length, Decls);
320 }
321
322 assert(!Decls.empty());
323
324 bool VisitedAtLeastOnce = false;
325 DeclContext *CurDC = 0;
Craig Topper2341c0d2013-07-04 03:08:24 +0000326 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
327 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000328 Decl *D = *DIt;
329 if (D->getSourceRange().isInvalid())
330 continue;
331
332 if (isInLexicalContext(D, CurDC))
333 continue;
334
335 CurDC = dyn_cast<DeclContext>(D);
336
337 if (TagDecl *TD = dyn_cast<TagDecl>(D))
338 if (!TD->isFreeStanding())
339 continue;
340
341 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
342 if (CompRes == RangeBefore)
343 continue;
344 if (CompRes == RangeAfter)
345 break;
346
347 assert(CompRes == RangeOverlap);
348 VisitedAtLeastOnce = true;
349
350 if (isa<ObjCContainerDecl>(D)) {
351 FileDI_current = &DIt;
352 FileDE_current = DE;
353 } else {
354 FileDI_current = 0;
355 }
356
357 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000358 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000359 }
360
361 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000362 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363
364 // No Decls overlapped with the range. Move up the lexical context until there
365 // is a context that contains the range or we reach the translation unit
366 // level.
367 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
368 : (*(DIt-1))->getLexicalDeclContext();
369
370 while (DC && !DC->isTranslationUnit()) {
371 Decl *D = cast<Decl>(DC);
372 SourceRange CurDeclRange = D->getSourceRange();
373 if (CurDeclRange.isInvalid())
374 break;
375
376 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000377 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
378 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000379 }
380
381 DC = D->getLexicalDeclContext();
382 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000383
384 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000385}
386
387bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
388 if (!AU->getPreprocessor().getPreprocessingRecord())
389 return false;
390
391 PreprocessingRecord &PPRec
392 = *AU->getPreprocessor().getPreprocessingRecord();
393 SourceManager &SM = AU->getSourceManager();
394
395 if (RegionOfInterest.isValid()) {
396 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
397 SourceLocation B = MappedRange.getBegin();
398 SourceLocation E = MappedRange.getEnd();
399
400 if (AU->isInPreambleFileID(B)) {
401 if (SM.isLoadedSourceLocation(E))
402 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
403 PPRec, *this);
404
405 // Beginning of range lies in the preamble but it also extends beyond
406 // it into the main file. Split the range into 2 parts, one covering
407 // the preamble and another covering the main file. This allows subsequent
408 // calls to visitPreprocessedEntitiesInRange to accept a source range that
409 // lies in the same FileID, allowing it to skip preprocessed entities that
410 // do not come from the same FileID.
411 bool breaked =
412 visitPreprocessedEntitiesInRange(
413 SourceRange(B, AU->getEndOfPreambleFileID()),
414 PPRec, *this);
415 if (breaked) return true;
416 return visitPreprocessedEntitiesInRange(
417 SourceRange(AU->getStartOfMainFileID(), E),
418 PPRec, *this);
419 }
420
421 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
422 }
423
424 bool OnlyLocalDecls
425 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
426
427 if (OnlyLocalDecls)
428 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
429 PPRec);
430
431 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
432}
433
434template<typename InputIterator>
435bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
436 InputIterator Last,
437 PreprocessingRecord &PPRec,
438 FileID FID) {
439 for (; First != Last; ++First) {
440 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
441 continue;
442
443 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000444 if (!PPE)
445 continue;
446
Guy Benyei11169dd2012-12-18 14:30:41 +0000447 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
448 if (Visit(MakeMacroExpansionCursor(ME, TU)))
449 return true;
450
451 continue;
452 }
453
454 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
455 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
456 return true;
457
458 continue;
459 }
460
461 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
462 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
463 return true;
464
465 continue;
466 }
467 }
468
469 return false;
470}
471
472/// \brief Visit the children of the given cursor.
473///
474/// \returns true if the visitation should be aborted, false if it
475/// should continue.
476bool CursorVisitor::VisitChildren(CXCursor Cursor) {
477 if (clang_isReference(Cursor.kind) &&
478 Cursor.kind != CXCursor_CXXBaseSpecifier) {
479 // By definition, references have no children.
480 return false;
481 }
482
483 // Set the Parent field to Cursor, then back to its old value once we're
484 // done.
485 SetParentRAII SetParent(Parent, StmtParent, Cursor);
486
487 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000488 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000489 if (!D)
490 return false;
491
492 return VisitAttributes(D) || Visit(D);
493 }
494
495 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000496 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 return Visit(S);
498
499 return false;
500 }
501
502 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000503 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000504 return Visit(E);
505
506 return false;
507 }
508
509 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000510 CXTranslationUnit TU = getCursorTU(Cursor);
511 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000512
513 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
514 for (unsigned I = 0; I != 2; ++I) {
515 if (VisitOrder[I]) {
516 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
517 RegionOfInterest.isInvalid()) {
518 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
519 TLEnd = CXXUnit->top_level_end();
520 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000521 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000522 return true;
523 }
524 } else if (VisitDeclContext(
525 CXXUnit->getASTContext().getTranslationUnitDecl()))
526 return true;
527 continue;
528 }
529
530 // Walk the preprocessing record.
531 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
532 visitPreprocessedEntitiesInRegion();
533 }
534
535 return false;
536 }
537
538 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000539 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000540 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
541 return Visit(BaseTSInfo->getTypeLoc());
542 }
543 }
544 }
545
546 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000547 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000549 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000550 return Visit(cxcursor::MakeCursorObjCClassRef(
551 ObjT->getInterface(),
552 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000553 }
554
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000555 // If pointing inside a macro definition, check if the token is an identifier
556 // that was ever defined as a macro. In such a case, create a "pseudo" macro
557 // expansion cursor for that token.
558 SourceLocation BeginLoc = RegionOfInterest.getBegin();
559 if (Cursor.kind == CXCursor_MacroDefinition &&
560 BeginLoc == RegionOfInterest.getEnd()) {
561 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000562 const MacroInfo *MI =
563 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000564 if (MacroDefinition *MacroDef =
565 checkForMacroInMacroDefinition(MI, Loc, TU))
566 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
567 }
568
Guy Benyei11169dd2012-12-18 14:30:41 +0000569 // Nothing to visit at the moment.
570 return false;
571}
572
573bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
574 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
575 if (Visit(TSInfo->getTypeLoc()))
576 return true;
577
578 if (Stmt *Body = B->getBody())
579 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
580
581 return false;
582}
583
Ted Kremenek03325582013-02-21 01:29:01 +0000584Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000585 if (RegionOfInterest.isValid()) {
586 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
587 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000588 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000589
590 switch (CompareRegionOfInterest(Range)) {
591 case RangeBefore:
592 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000593 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000594
595 case RangeAfter:
596 // This declaration comes after the region of interest; we're done.
597 return false;
598
599 case RangeOverlap:
600 // This declaration overlaps the region of interest; visit it.
601 break;
602 }
603 }
604 return true;
605}
606
607bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
608 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
609
610 // FIXME: Eventually remove. This part of a hack to support proper
611 // iteration over all Decls contained lexically within an ObjC container.
612 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
613 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
614
615 for ( ; I != E; ++I) {
616 Decl *D = *I;
617 if (D->getLexicalDeclContext() != DC)
618 continue;
619 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
620
621 // Ignore synthesized ivars here, otherwise if we have something like:
622 // @synthesize prop = _prop;
623 // and '_prop' is not declared, we will encounter a '_prop' ivar before
624 // encountering the 'prop' synthesize declaration and we will think that
625 // we passed the region-of-interest.
626 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
627 if (ivarD->getSynthesize())
628 continue;
629 }
630
631 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
632 // declarations is a mismatch with the compiler semantics.
633 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
634 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
635 if (!ID->isThisDeclarationADefinition())
636 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
637
638 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
639 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
640 if (!PD->isThisDeclarationADefinition())
641 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
642 }
643
Ted Kremenek03325582013-02-21 01:29:01 +0000644 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000645 if (!V.hasValue())
646 continue;
647 if (!V.getValue())
648 return false;
649 if (Visit(Cursor, true))
650 return true;
651 }
652 return false;
653}
654
655bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
656 llvm_unreachable("Translation units are visited directly by Visit()");
657}
658
659bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
660 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
661 return Visit(TSInfo->getTypeLoc());
662
663 return false;
664}
665
666bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
667 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
668 return Visit(TSInfo->getTypeLoc());
669
670 return false;
671}
672
673bool CursorVisitor::VisitTagDecl(TagDecl *D) {
674 return VisitDeclContext(D);
675}
676
677bool CursorVisitor::VisitClassTemplateSpecializationDecl(
678 ClassTemplateSpecializationDecl *D) {
679 bool ShouldVisitBody = false;
680 switch (D->getSpecializationKind()) {
681 case TSK_Undeclared:
682 case TSK_ImplicitInstantiation:
683 // Nothing to visit
684 return false;
685
686 case TSK_ExplicitInstantiationDeclaration:
687 case TSK_ExplicitInstantiationDefinition:
688 break;
689
690 case TSK_ExplicitSpecialization:
691 ShouldVisitBody = true;
692 break;
693 }
694
695 // Visit the template arguments used in the specialization.
696 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
697 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000698 if (TemplateSpecializationTypeLoc TSTLoc =
699 TL.getAs<TemplateSpecializationTypeLoc>()) {
700 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
701 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000702 return true;
703 }
704 }
705
706 if (ShouldVisitBody && VisitCXXRecordDecl(D))
707 return true;
708
709 return false;
710}
711
712bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
713 ClassTemplatePartialSpecializationDecl *D) {
714 // FIXME: Visit the "outer" template parameter lists on the TagDecl
715 // before visiting these template parameters.
716 if (VisitTemplateParameters(D->getTemplateParameters()))
717 return true;
718
719 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000720 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
721 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
722 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000723 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
724 return true;
725
726 return VisitCXXRecordDecl(D);
727}
728
729bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
730 // Visit the default argument.
731 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
732 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
733 if (Visit(DefArg->getTypeLoc()))
734 return true;
735
736 return false;
737}
738
739bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
740 if (Expr *Init = D->getInitExpr())
741 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
742 return false;
743}
744
745bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000746 unsigned NumParamList = DD->getNumTemplateParameterLists();
747 for (unsigned i = 0; i < NumParamList; i++) {
748 TemplateParameterList* Params = DD->getTemplateParameterList(i);
749 if (VisitTemplateParameters(Params))
750 return true;
751 }
752
Guy Benyei11169dd2012-12-18 14:30:41 +0000753 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
754 if (Visit(TSInfo->getTypeLoc()))
755 return true;
756
757 // Visit the nested-name-specifier, if present.
758 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
759 if (VisitNestedNameSpecifierLoc(QualifierLoc))
760 return true;
761
762 return false;
763}
764
765/// \brief Compare two base or member initializers based on their source order.
Benjamin Kramer04bf1872013-09-22 14:10:29 +0000766static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
767 CXXCtorInitializer *const *Y) {
768 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
Guy Benyei11169dd2012-12-18 14:30:41 +0000769}
770
771bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000772 unsigned NumParamList = ND->getNumTemplateParameterLists();
773 for (unsigned i = 0; i < NumParamList; i++) {
774 TemplateParameterList* Params = ND->getTemplateParameterList(i);
775 if (VisitTemplateParameters(Params))
776 return true;
777 }
778
Guy Benyei11169dd2012-12-18 14:30:41 +0000779 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
780 // Visit the function declaration's syntactic components in the order
781 // written. This requires a bit of work.
782 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000783 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000784
785 // If we have a function declared directly (without the use of a typedef),
786 // visit just the return type. Otherwise, just visit the function's type
787 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000788 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000789 (!FTL && Visit(TL)))
790 return true;
791
792 // Visit the nested-name-specifier, if present.
793 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
794 if (VisitNestedNameSpecifierLoc(QualifierLoc))
795 return true;
796
797 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000798 if (!isa<CXXDestructorDecl>(ND))
799 if (VisitDeclarationNameInfo(ND->getNameInfo()))
800 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000801
802 // FIXME: Visit explicitly-specified template arguments!
803
804 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000805 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000806 return true;
807
Bill Wendling44426052012-12-20 19:22:21 +0000808 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000809 }
810
811 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
812 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
813 // Find the initializers that were written in the source.
814 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
815 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
816 IEnd = Constructor->init_end();
817 I != IEnd; ++I) {
818 if (!(*I)->isWritten())
819 continue;
820
821 WrittenInits.push_back(*I);
822 }
823
824 // Sort the initializers in source order
825 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
826 &CompareCXXCtorInitializers);
827
828 // Visit the initializers in source order
829 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
830 CXXCtorInitializer *Init = WrittenInits[I];
831 if (Init->isAnyMemberInitializer()) {
832 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
833 Init->getMemberLocation(), TU)))
834 return true;
835 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
836 if (Visit(TInfo->getTypeLoc()))
837 return true;
838 }
839
840 // Visit the initializer value.
841 if (Expr *Initializer = Init->getInit())
842 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
843 return true;
844 }
845 }
846
847 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
848 return true;
849 }
850
851 return false;
852}
853
854bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
855 if (VisitDeclaratorDecl(D))
856 return true;
857
858 if (Expr *BitWidth = D->getBitWidth())
859 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
860
861 return false;
862}
863
864bool CursorVisitor::VisitVarDecl(VarDecl *D) {
865 if (VisitDeclaratorDecl(D))
866 return true;
867
868 if (Expr *Init = D->getInit())
869 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
870
871 return false;
872}
873
874bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
875 if (VisitDeclaratorDecl(D))
876 return true;
877
878 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
879 if (Expr *DefArg = D->getDefaultArgument())
880 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
881
882 return false;
883}
884
885bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
886 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
887 // before visiting these template parameters.
888 if (VisitTemplateParameters(D->getTemplateParameters()))
889 return true;
890
891 return VisitFunctionDecl(D->getTemplatedDecl());
892}
893
894bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
895 // FIXME: Visit the "outer" template parameter lists on the TagDecl
896 // before visiting these template parameters.
897 if (VisitTemplateParameters(D->getTemplateParameters()))
898 return true;
899
900 return VisitCXXRecordDecl(D->getTemplatedDecl());
901}
902
903bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
904 if (VisitTemplateParameters(D->getTemplateParameters()))
905 return true;
906
907 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
908 VisitTemplateArgumentLoc(D->getDefaultArgument()))
909 return true;
910
911 return false;
912}
913
914bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000915 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000916 if (Visit(TSInfo->getTypeLoc()))
917 return true;
918
Aaron Ballman43b68be2014-03-07 17:50:17 +0000919 for (const auto *P : ND->params()) {
920 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000921 return true;
922 }
923
924 if (ND->isThisDeclarationADefinition() &&
925 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
926 return true;
927
928 return false;
929}
930
931template <typename DeclIt>
932static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
933 SourceManager &SM, SourceLocation EndLoc,
934 SmallVectorImpl<Decl *> &Decls) {
935 DeclIt next = *DI_current;
936 while (++next != DE_current) {
937 Decl *D_next = *next;
938 if (!D_next)
939 break;
940 SourceLocation L = D_next->getLocStart();
941 if (!L.isValid())
942 break;
943 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
944 *DI_current = next;
945 Decls.push_back(D_next);
946 continue;
947 }
948 break;
949 }
950}
951
Guy Benyei11169dd2012-12-18 14:30:41 +0000952bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
953 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
954 // an @implementation can lexically contain Decls that are not properly
955 // nested in the AST. When we identify such cases, we need to retrofit
956 // this nesting here.
957 if (!DI_current && !FileDI_current)
958 return VisitDeclContext(D);
959
960 // Scan the Decls that immediately come after the container
961 // in the current DeclContext. If any fall within the
962 // container's lexical region, stash them into a vector
963 // for later processing.
964 SmallVector<Decl *, 24> DeclsInContainer;
965 SourceLocation EndLoc = D->getSourceRange().getEnd();
966 SourceManager &SM = AU->getSourceManager();
967 if (EndLoc.isValid()) {
968 if (DI_current) {
969 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
970 DeclsInContainer);
971 } else {
972 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
973 DeclsInContainer);
974 }
975 }
976
977 // The common case.
978 if (DeclsInContainer.empty())
979 return VisitDeclContext(D);
980
981 // Get all the Decls in the DeclContext, and sort them with the
982 // additional ones we've collected. Then visit them.
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 Ballman7dce1a82014-03-07 13:13:38 +00001674 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1675 i != e; ++i)
1676 if (Visit(MakeCXCursor(*i, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001677 return true;
1678
1679 return false;
1680}
1681
1682//===----------------------------------------------------------------------===//
1683// Data-recursive visitor methods.
1684//===----------------------------------------------------------------------===//
1685
1686namespace {
1687#define DEF_JOB(NAME, DATA, KIND)\
1688class NAME : public VisitorJob {\
1689public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001690 NAME(const DATA *d, CXCursor parent) : \
1691 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001692 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001693 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001694};
1695
1696DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1697DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1698DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1699DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1700DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1701 ExplicitTemplateArgsVisitKind)
1702DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1703DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1704DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1705#undef DEF_JOB
1706
1707class DeclVisit : public VisitorJob {
1708public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001709 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001710 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001711 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001712 static bool classof(const VisitorJob *VJ) {
1713 return VJ->getKind() == DeclVisitKind;
1714 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001715 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001716 bool isFirst() const { return data[1] ? true : false; }
1717};
1718class TypeLocVisit : public VisitorJob {
1719public:
1720 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1721 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1722 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1723
1724 static bool classof(const VisitorJob *VJ) {
1725 return VJ->getKind() == TypeLocVisitKind;
1726 }
1727
1728 TypeLoc get() const {
1729 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001730 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001731 }
1732};
1733
1734class LabelRefVisit : public VisitorJob {
1735public:
1736 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1737 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1738 labelLoc.getPtrEncoding()) {}
1739
1740 static bool classof(const VisitorJob *VJ) {
1741 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1742 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001743 const LabelDecl *get() const {
1744 return static_cast<const LabelDecl *>(data[0]);
1745 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001746 SourceLocation getLoc() const {
1747 return SourceLocation::getFromPtrEncoding(data[1]); }
1748};
1749
1750class NestedNameSpecifierLocVisit : public VisitorJob {
1751public:
1752 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1753 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1754 Qualifier.getNestedNameSpecifier(),
1755 Qualifier.getOpaqueData()) { }
1756
1757 static bool classof(const VisitorJob *VJ) {
1758 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1759 }
1760
1761 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001762 return NestedNameSpecifierLoc(
1763 const_cast<NestedNameSpecifier *>(
1764 static_cast<const NestedNameSpecifier *>(data[0])),
1765 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001766 }
1767};
1768
1769class DeclarationNameInfoVisit : public VisitorJob {
1770public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001771 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001772 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001773 static bool classof(const VisitorJob *VJ) {
1774 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1775 }
1776 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001777 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001778 switch (S->getStmtClass()) {
1779 default:
1780 llvm_unreachable("Unhandled Stmt");
1781 case clang::Stmt::MSDependentExistsStmtClass:
1782 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1783 case Stmt::CXXDependentScopeMemberExprClass:
1784 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1785 case Stmt::DependentScopeDeclRefExprClass:
1786 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1787 }
1788 }
1789};
1790class MemberRefVisit : public VisitorJob {
1791public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001792 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001793 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1794 L.getPtrEncoding()) {}
1795 static bool classof(const VisitorJob *VJ) {
1796 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1797 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001798 const FieldDecl *get() const {
1799 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001800 }
1801 SourceLocation getLoc() const {
1802 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1803 }
1804};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001805class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001806 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001807 VisitorWorkList &WL;
1808 CXCursor Parent;
1809public:
1810 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1811 : WL(wl), Parent(parent) {}
1812
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001813 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1814 void VisitBlockExpr(const BlockExpr *B);
1815 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1816 void VisitCompoundStmt(const CompoundStmt *S);
1817 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1818 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1819 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1820 void VisitCXXNewExpr(const CXXNewExpr *E);
1821 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1822 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1823 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1824 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1825 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1826 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1827 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1828 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1829 void VisitDeclRefExpr(const DeclRefExpr *D);
1830 void VisitDeclStmt(const DeclStmt *S);
1831 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1832 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1833 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1834 void VisitForStmt(const ForStmt *FS);
1835 void VisitGotoStmt(const GotoStmt *GS);
1836 void VisitIfStmt(const IfStmt *If);
1837 void VisitInitListExpr(const InitListExpr *IE);
1838 void VisitMemberExpr(const MemberExpr *M);
1839 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1840 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1841 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1842 void VisitOverloadExpr(const OverloadExpr *E);
1843 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1844 void VisitStmt(const Stmt *S);
1845 void VisitSwitchStmt(const SwitchStmt *S);
1846 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001847 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1848 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1849 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1850 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1851 void VisitVAArgExpr(const VAArgExpr *E);
1852 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1853 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1854 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1855 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001856 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1857 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001858 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001859
Guy Benyei11169dd2012-12-18 14:30:41 +00001860private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001861 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001862 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1863 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001864 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1865 void AddStmt(const Stmt *S);
1866 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001867 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001868 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001869 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001870};
1871} // end anonyous namespace
1872
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001873void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001874 // 'S' should always be non-null, since it comes from the
1875 // statement we are visiting.
1876 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1877}
1878
1879void
1880EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1881 if (Qualifier)
1882 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1883}
1884
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001885void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001886 if (S)
1887 WL.push_back(StmtVisit(S, Parent));
1888}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001889void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001890 if (D)
1891 WL.push_back(DeclVisit(D, Parent, isFirst));
1892}
1893void EnqueueVisitor::
1894 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1895 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001896 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001897}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001898void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001899 if (D)
1900 WL.push_back(MemberRefVisit(D, L, Parent));
1901}
1902void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1903 if (TI)
1904 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1905 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001906void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001907 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001908 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001909 AddStmt(*Child);
1910 }
1911 if (size == WL.size())
1912 return;
1913 // Now reverse the entries we just added. This will match the DFS
1914 // ordering performed by the worklist.
1915 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1916 std::reverse(I, E);
1917}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001918namespace {
1919class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1920 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001921 /// \brief Process clauses with list of variables.
1922 template <typename T>
1923 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001924public:
1925 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1926#define OPENMP_CLAUSE(Name, Class) \
1927 void Visit##Class(const Class *C);
1928#include "clang/Basic/OpenMPKinds.def"
1929};
1930
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001931void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1932 Visitor->AddStmt(C->getCondition());
1933}
1934
Alexey Bataev568a8332014-03-06 06:15:19 +00001935void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1936 Visitor->AddStmt(C->getNumThreads());
1937}
1938
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001939void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001940
1941template<typename T>
1942void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
1943 for (typename T::varlist_const_iterator I = Node->varlist_begin(),
1944 E = Node->varlist_end();
1945 I != E; ++I)
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001946 Visitor->AddStmt(*I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001947}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001948
1949void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001950 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001951}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001952void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1953 const OMPFirstprivateClause *C) {
1954 VisitOMPClauseList(C);
1955}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001956void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001957 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001958}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001959}
Alexey Bataev756c1962013-09-24 03:17:45 +00001960
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001961void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1962 unsigned size = WL.size();
1963 OMPClauseEnqueue Visitor(this);
1964 Visitor.Visit(S);
1965 if (size == WL.size())
1966 return;
1967 // Now reverse the entries we just added. This will match the DFS
1968 // ordering performed by the worklist.
1969 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1970 std::reverse(I, E);
1971}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001972void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001973 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1974}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001975void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001976 AddDecl(B->getBlockDecl());
1977}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001978void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001979 EnqueueChildren(E);
1980 AddTypeLoc(E->getTypeSourceInfo());
1981}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001982void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1983 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001984 E = S->body_rend(); I != E; ++I) {
1985 AddStmt(*I);
1986 }
1987}
1988void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001989VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001990 AddStmt(S->getSubStmt());
1991 AddDeclarationNameInfo(S);
1992 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1993 AddNestedNameSpecifierLoc(QualifierLoc);
1994}
1995
1996void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001997VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001998 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1999 AddDeclarationNameInfo(E);
2000 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2001 AddNestedNameSpecifierLoc(QualifierLoc);
2002 if (!E->isImplicitAccess())
2003 AddStmt(E->getBase());
2004}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002005void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002006 // Enqueue the initializer , if any.
2007 AddStmt(E->getInitializer());
2008 // Enqueue the array size, if any.
2009 AddStmt(E->getArraySize());
2010 // Enqueue the allocated type.
2011 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2012 // Enqueue the placement arguments.
2013 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2014 AddStmt(E->getPlacementArg(I-1));
2015}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002016void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002017 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2018 AddStmt(CE->getArg(I-1));
2019 AddStmt(CE->getCallee());
2020 AddStmt(CE->getArg(0));
2021}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002022void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2023 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002024 // Visit the name of the type being destroyed.
2025 AddTypeLoc(E->getDestroyedTypeInfo());
2026 // Visit the scope type that looks disturbingly like the nested-name-specifier
2027 // but isn't.
2028 AddTypeLoc(E->getScopeTypeInfo());
2029 // Visit the nested-name-specifier.
2030 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2031 AddNestedNameSpecifierLoc(QualifierLoc);
2032 // Visit base expression.
2033 AddStmt(E->getBase());
2034}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002035void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2036 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002037 AddTypeLoc(E->getTypeSourceInfo());
2038}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002039void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2040 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002041 EnqueueChildren(E);
2042 AddTypeLoc(E->getTypeSourceInfo());
2043}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002044void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002045 EnqueueChildren(E);
2046 if (E->isTypeOperand())
2047 AddTypeLoc(E->getTypeOperandSourceInfo());
2048}
2049
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002050void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2051 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002052 EnqueueChildren(E);
2053 AddTypeLoc(E->getTypeSourceInfo());
2054}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002055void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002056 EnqueueChildren(E);
2057 if (E->isTypeOperand())
2058 AddTypeLoc(E->getTypeOperandSourceInfo());
2059}
2060
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002061void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002062 EnqueueChildren(S);
2063 AddDecl(S->getExceptionDecl());
2064}
2065
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002066void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002067 if (DR->hasExplicitTemplateArgs()) {
2068 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2069 }
2070 WL.push_back(DeclRefExprParts(DR, Parent));
2071}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002072void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2073 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002074 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2075 AddDeclarationNameInfo(E);
2076 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2077}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002078void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002079 unsigned size = WL.size();
2080 bool isFirst = true;
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002081 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00002082 D != DEnd; ++D) {
2083 AddDecl(*D, isFirst);
2084 isFirst = false;
2085 }
2086 if (size == WL.size())
2087 return;
2088 // Now reverse the entries we just added. This will match the DFS
2089 // ordering performed by the worklist.
2090 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2091 std::reverse(I, E);
2092}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002093void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002094 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002095 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002096 D = E->designators_rbegin(), DEnd = E->designators_rend();
2097 D != DEnd; ++D) {
2098 if (D->isFieldDesignator()) {
2099 if (FieldDecl *Field = D->getField())
2100 AddMemberRef(Field, D->getFieldLoc());
2101 continue;
2102 }
2103 if (D->isArrayDesignator()) {
2104 AddStmt(E->getArrayIndex(*D));
2105 continue;
2106 }
2107 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2108 AddStmt(E->getArrayRangeEnd(*D));
2109 AddStmt(E->getArrayRangeStart(*D));
2110 }
2111}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002112void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002113 EnqueueChildren(E);
2114 AddTypeLoc(E->getTypeInfoAsWritten());
2115}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002116void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002117 AddStmt(FS->getBody());
2118 AddStmt(FS->getInc());
2119 AddStmt(FS->getCond());
2120 AddDecl(FS->getConditionVariable());
2121 AddStmt(FS->getInit());
2122}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002123void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002124 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2125}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002126void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002127 AddStmt(If->getElse());
2128 AddStmt(If->getThen());
2129 AddStmt(If->getCond());
2130 AddDecl(If->getConditionVariable());
2131}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002132void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002133 // We care about the syntactic form of the initializer list, only.
2134 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2135 IE = Syntactic;
2136 EnqueueChildren(IE);
2137}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002138void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002139 WL.push_back(MemberExprParts(M, Parent));
2140
2141 // If the base of the member access expression is an implicit 'this', don't
2142 // visit it.
2143 // FIXME: If we ever want to show these implicit accesses, this will be
2144 // unfortunate. However, clang_getCursor() relies on this behavior.
2145 if (!M->isImplicitAccess())
2146 AddStmt(M->getBase());
2147}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002148void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002149 AddTypeLoc(E->getEncodedTypeSourceInfo());
2150}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002151void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002152 EnqueueChildren(M);
2153 AddTypeLoc(M->getClassReceiverTypeInfo());
2154}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002155void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002156 // Visit the components of the offsetof expression.
2157 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2158 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2159 const OffsetOfNode &Node = E->getComponent(I-1);
2160 switch (Node.getKind()) {
2161 case OffsetOfNode::Array:
2162 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2163 break;
2164 case OffsetOfNode::Field:
2165 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2166 break;
2167 case OffsetOfNode::Identifier:
2168 case OffsetOfNode::Base:
2169 continue;
2170 }
2171 }
2172 // Visit the type into which we're computing the offset.
2173 AddTypeLoc(E->getTypeSourceInfo());
2174}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002175void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002176 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2177 WL.push_back(OverloadExprParts(E, Parent));
2178}
2179void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002180 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002181 EnqueueChildren(E);
2182 if (E->isArgumentType())
2183 AddTypeLoc(E->getArgumentTypeInfo());
2184}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002185void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002186 EnqueueChildren(S);
2187}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002188void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002189 AddStmt(S->getBody());
2190 AddStmt(S->getCond());
2191 AddDecl(S->getConditionVariable());
2192}
2193
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002194void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002195 AddStmt(W->getBody());
2196 AddStmt(W->getCond());
2197 AddDecl(W->getConditionVariable());
2198}
2199
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002200void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002201 for (unsigned I = E->getNumArgs(); I > 0; --I)
2202 AddTypeLoc(E->getArg(I-1));
2203}
2204
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002205void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002206 AddTypeLoc(E->getQueriedTypeSourceInfo());
2207}
2208
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002209void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002210 EnqueueChildren(E);
2211}
2212
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002213void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002214 VisitOverloadExpr(U);
2215 if (!U->isImplicitAccess())
2216 AddStmt(U->getBase());
2217}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 AddStmt(E->getSubExpr());
2220 AddTypeLoc(E->getWrittenTypeInfo());
2221}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002222void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002223 WL.push_back(SizeOfPackExprParts(E, Parent));
2224}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002225void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002226 // If the opaque value has a source expression, just transparently
2227 // visit that. This is useful for (e.g.) pseudo-object expressions.
2228 if (Expr *SourceExpr = E->getSourceExpr())
2229 return Visit(SourceExpr);
2230}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002231void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002232 AddStmt(E->getBody());
2233 WL.push_back(LambdaExprParts(E, Parent));
2234}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002235void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002236 // Treat the expression like its syntactic form.
2237 Visit(E->getSyntacticForm());
2238}
2239
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002240void EnqueueVisitor::VisitOMPExecutableDirective(
2241 const OMPExecutableDirective *D) {
2242 EnqueueChildren(D);
2243 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2244 E = D->clauses().end();
2245 I != E; ++I)
2246 EnqueueChildren(*I);
2247}
2248
2249void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2250 VisitOMPExecutableDirective(D);
2251}
2252
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002253void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2254 VisitOMPExecutableDirective(D);
2255}
2256
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002257void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002258 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2259}
2260
2261bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2262 if (RegionOfInterest.isValid()) {
2263 SourceRange Range = getRawCursorExtent(C);
2264 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2265 return false;
2266 }
2267 return true;
2268}
2269
2270bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2271 while (!WL.empty()) {
2272 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002273 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002274
2275 // Set the Parent field, then back to its old value once we're done.
2276 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2277
2278 switch (LI.getKind()) {
2279 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002280 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002281 if (!D)
2282 continue;
2283
2284 // For now, perform default visitation for Decls.
2285 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2286 cast<DeclVisit>(&LI)->isFirst())))
2287 return true;
2288
2289 continue;
2290 }
2291 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2292 const ASTTemplateArgumentListInfo *ArgList =
2293 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2294 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2295 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2296 Arg != ArgEnd; ++Arg) {
2297 if (VisitTemplateArgumentLoc(*Arg))
2298 return true;
2299 }
2300 continue;
2301 }
2302 case VisitorJob::TypeLocVisitKind: {
2303 // Perform default visitation for TypeLocs.
2304 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2305 return true;
2306 continue;
2307 }
2308 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002309 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002310 if (LabelStmt *stmt = LS->getStmt()) {
2311 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2312 TU))) {
2313 return true;
2314 }
2315 }
2316 continue;
2317 }
2318
2319 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2320 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2321 if (VisitNestedNameSpecifierLoc(V->get()))
2322 return true;
2323 continue;
2324 }
2325
2326 case VisitorJob::DeclarationNameInfoVisitKind: {
2327 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2328 ->get()))
2329 return true;
2330 continue;
2331 }
2332 case VisitorJob::MemberRefVisitKind: {
2333 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2334 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2335 return true;
2336 continue;
2337 }
2338 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002339 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002340 if (!S)
2341 continue;
2342
2343 // Update the current cursor.
2344 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2345 if (!IsInRegionOfInterest(Cursor))
2346 continue;
2347 switch (Visitor(Cursor, Parent, ClientData)) {
2348 case CXChildVisit_Break: return true;
2349 case CXChildVisit_Continue: break;
2350 case CXChildVisit_Recurse:
2351 if (PostChildrenVisitor)
2352 WL.push_back(PostChildrenVisit(0, Cursor));
2353 EnqueueWorkList(WL, S);
2354 break;
2355 }
2356 continue;
2357 }
2358 case VisitorJob::MemberExprPartsKind: {
2359 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002360 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002361
2362 // Visit the nested-name-specifier
2363 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2364 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2365 return true;
2366
2367 // Visit the declaration name.
2368 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2369 return true;
2370
2371 // Visit the explicitly-specified template arguments, if any.
2372 if (M->hasExplicitTemplateArgs()) {
2373 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2374 *ArgEnd = Arg + M->getNumTemplateArgs();
2375 Arg != ArgEnd; ++Arg) {
2376 if (VisitTemplateArgumentLoc(*Arg))
2377 return true;
2378 }
2379 }
2380 continue;
2381 }
2382 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002383 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002384 // Visit nested-name-specifier, if present.
2385 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2386 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2387 return true;
2388 // Visit declaration name.
2389 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2390 return true;
2391 continue;
2392 }
2393 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002394 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002395 // Visit the nested-name-specifier.
2396 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2397 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2398 return true;
2399 // Visit the declaration name.
2400 if (VisitDeclarationNameInfo(O->getNameInfo()))
2401 return true;
2402 // Visit the overloaded declaration reference.
2403 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2404 return true;
2405 continue;
2406 }
2407 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002408 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002409 NamedDecl *Pack = E->getPack();
2410 if (isa<TemplateTypeParmDecl>(Pack)) {
2411 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2412 E->getPackLoc(), TU)))
2413 return true;
2414
2415 continue;
2416 }
2417
2418 if (isa<TemplateTemplateParmDecl>(Pack)) {
2419 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2420 E->getPackLoc(), TU)))
2421 return true;
2422
2423 continue;
2424 }
2425
2426 // Non-type template parameter packs and function parameter packs are
2427 // treated like DeclRefExpr cursors.
2428 continue;
2429 }
2430
2431 case VisitorJob::LambdaExprPartsKind: {
2432 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002433 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002434 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2435 CEnd = E->explicit_capture_end();
2436 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002437 // FIXME: Lambda init-captures.
2438 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002440
Guy Benyei11169dd2012-12-18 14:30:41 +00002441 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2442 C->getLocation(),
2443 TU)))
2444 return true;
2445 }
2446
2447 // Visit parameters and return type, if present.
2448 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2449 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2450 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2451 // Visit the whole type.
2452 if (Visit(TL))
2453 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002454 } else if (FunctionProtoTypeLoc Proto =
2455 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002456 if (E->hasExplicitParameters()) {
2457 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002458 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2459 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002460 return true;
2461 } else {
2462 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002463 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002464 return true;
2465 }
2466 }
2467 }
2468 break;
2469 }
2470
2471 case VisitorJob::PostChildrenVisitKind:
2472 if (PostChildrenVisitor(Parent, ClientData))
2473 return true;
2474 break;
2475 }
2476 }
2477 return false;
2478}
2479
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002480bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002481 VisitorWorkList *WL = 0;
2482 if (!WorkListFreeList.empty()) {
2483 WL = WorkListFreeList.back();
2484 WL->clear();
2485 WorkListFreeList.pop_back();
2486 }
2487 else {
2488 WL = new VisitorWorkList();
2489 WorkListCache.push_back(WL);
2490 }
2491 EnqueueWorkList(*WL, S);
2492 bool result = RunVisitorWorkList(*WL);
2493 WorkListFreeList.push_back(WL);
2494 return result;
2495}
2496
2497namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002498typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002499RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2500 const DeclarationNameInfo &NI,
2501 const SourceRange &QLoc,
2502 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2503 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2504 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2505 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2506
2507 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2508
2509 RefNamePieces Pieces;
2510
2511 if (WantQualifier && QLoc.isValid())
2512 Pieces.push_back(QLoc);
2513
2514 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2515 Pieces.push_back(NI.getLoc());
2516
2517 if (WantTemplateArgs && TemplateArgs)
2518 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2519 TemplateArgs->RAngleLoc));
2520
2521 if (Kind == DeclarationName::CXXOperatorName) {
2522 Pieces.push_back(SourceLocation::getFromRawEncoding(
2523 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2524 Pieces.push_back(SourceLocation::getFromRawEncoding(
2525 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2526 }
2527
2528 if (WantSinglePiece) {
2529 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2530 Pieces.clear();
2531 Pieces.push_back(R);
2532 }
2533
2534 return Pieces;
2535}
2536}
2537
2538//===----------------------------------------------------------------------===//
2539// Misc. API hooks.
2540//===----------------------------------------------------------------------===//
2541
2542static llvm::sys::Mutex EnableMultithreadingMutex;
2543static bool EnabledMultithreading;
2544
Chad Rosier05c71aa2013-03-27 18:28:23 +00002545static void fatal_error_handler(void *user_data, const std::string& reason,
2546 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002547 // Write the result out to stderr avoiding errs() because raw_ostreams can
2548 // call report_fatal_error.
2549 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2550 ::abort();
2551}
2552
2553extern "C" {
2554CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2555 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002556 // We use crash recovery to make some of our APIs more reliable, implicitly
2557 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002558 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2559 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002560
2561 // Enable support for multithreading in LLVM.
2562 {
2563 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2564 if (!EnabledMultithreading) {
2565 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2566 llvm::llvm_start_multithreaded();
2567 EnabledMultithreading = true;
2568 }
2569 }
2570
2571 CIndexer *CIdxr = new CIndexer();
2572 if (excludeDeclarationsFromPCH)
2573 CIdxr->setOnlyLocalDecls();
2574 if (displayDiagnostics)
2575 CIdxr->setDisplayDiagnostics();
2576
2577 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2578 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2579 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2580 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2581 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2582 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2583
2584 return CIdxr;
2585}
2586
2587void clang_disposeIndex(CXIndex CIdx) {
2588 if (CIdx)
2589 delete static_cast<CIndexer *>(CIdx);
2590}
2591
2592void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2593 if (CIdx)
2594 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2595}
2596
2597unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2598 if (CIdx)
2599 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2600 return 0;
2601}
2602
2603void clang_toggleCrashRecovery(unsigned isEnabled) {
2604 if (isEnabled)
2605 llvm::CrashRecoveryContext::Enable();
2606 else
2607 llvm::CrashRecoveryContext::Disable();
2608}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002609
Guy Benyei11169dd2012-12-18 14:30:41 +00002610CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2611 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002612 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002613 enum CXErrorCode Result =
2614 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002615 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002616 assert((TU && Result == CXError_Success) ||
2617 (!TU && Result != CXError_Success));
2618 return TU;
2619}
2620
2621enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2622 const char *ast_filename,
2623 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002624 if (out_TU)
2625 *out_TU = NULL;
2626
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002627 if (!CIdx || !ast_filename || !out_TU)
2628 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002629
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002630 LOG_FUNC_SECTION {
2631 *Log << ast_filename;
2632 }
2633
Guy Benyei11169dd2012-12-18 14:30:41 +00002634 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2635 FileSystemOptions FileSystemOpts;
2636
2637 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002638 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002639 CXXIdx->getOnlyLocalDecls(), None,
2640 /*CaptureDiagnostics=*/true,
2641 /*AllowPCHWithCompilerErrors=*/true,
2642 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002643 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2644 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002645}
2646
2647unsigned clang_defaultEditingTranslationUnitOptions() {
2648 return CXTranslationUnit_PrecompiledPreamble |
2649 CXTranslationUnit_CacheCompletionResults;
2650}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002651
Guy Benyei11169dd2012-12-18 14:30:41 +00002652CXTranslationUnit
2653clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2654 const char *source_filename,
2655 int num_command_line_args,
2656 const char * const *command_line_args,
2657 unsigned num_unsaved_files,
2658 struct CXUnsavedFile *unsaved_files) {
2659 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2660 return clang_parseTranslationUnit(CIdx, source_filename,
2661 command_line_args, num_command_line_args,
2662 unsaved_files, num_unsaved_files,
2663 Options);
2664}
2665
2666struct ParseTranslationUnitInfo {
2667 CXIndex CIdx;
2668 const char *source_filename;
2669 const char *const *command_line_args;
2670 int num_command_line_args;
2671 struct CXUnsavedFile *unsaved_files;
2672 unsigned num_unsaved_files;
2673 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002674 CXTranslationUnit *out_TU;
2675 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002676};
2677static void clang_parseTranslationUnit_Impl(void *UserData) {
2678 ParseTranslationUnitInfo *PTUI =
2679 static_cast<ParseTranslationUnitInfo*>(UserData);
2680 CXIndex CIdx = PTUI->CIdx;
2681 const char *source_filename = PTUI->source_filename;
2682 const char * const *command_line_args = PTUI->command_line_args;
2683 int num_command_line_args = PTUI->num_command_line_args;
2684 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2685 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2686 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002687 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002688
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002689 // Set up the initial return values.
2690 if (out_TU)
2691 *out_TU = NULL;
2692 PTUI->result = CXError_Failure;
2693
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002694 // Check arguments.
2695 if (!CIdx || !out_TU ||
2696 (unsaved_files == NULL && num_unsaved_files != 0)) {
2697 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002698 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002699 }
2700
Guy Benyei11169dd2012-12-18 14:30:41 +00002701 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2702
2703 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2704 setThreadBackgroundPriority();
2705
2706 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2707 // FIXME: Add a flag for modules.
2708 TranslationUnitKind TUKind
2709 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002710 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002711 = options & CXTranslationUnit_CacheCompletionResults;
2712 bool IncludeBriefCommentsInCodeCompletion
2713 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2714 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2715 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2716
2717 // Configure the diagnostics.
2718 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002719 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002720
2721 // Recover resources if we crash before exiting this function.
2722 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2723 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2724 DiagCleanup(Diags.getPtr());
2725
2726 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2727 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2728
2729 // Recover resources if we crash before exiting this function.
2730 llvm::CrashRecoveryContextCleanupRegistrar<
2731 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2732
2733 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2734 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2735 const llvm::MemoryBuffer *Buffer
2736 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2737 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2738 Buffer));
2739 }
2740
2741 OwningPtr<std::vector<const char *> >
2742 Args(new std::vector<const char*>());
2743
2744 // Recover resources if we crash before exiting this method.
2745 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2746 ArgsCleanup(Args.get());
2747
2748 // Since the Clang C library is primarily used by batch tools dealing with
2749 // (often very broken) source code, where spell-checking can have a
2750 // significant negative impact on performance (particularly when
2751 // precompiled headers are involved), we disable it by default.
2752 // Only do this if we haven't found a spell-checking-related argument.
2753 bool FoundSpellCheckingArgument = false;
2754 for (int I = 0; I != num_command_line_args; ++I) {
2755 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2756 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2757 FoundSpellCheckingArgument = true;
2758 break;
2759 }
2760 }
2761 if (!FoundSpellCheckingArgument)
2762 Args->push_back("-fno-spell-checking");
2763
2764 Args->insert(Args->end(), command_line_args,
2765 command_line_args + num_command_line_args);
2766
2767 // The 'source_filename' argument is optional. If the caller does not
2768 // specify it then it is assumed that the source file is specified
2769 // in the actual argument list.
2770 // Put the source file after command_line_args otherwise if '-x' flag is
2771 // present it will be unused.
2772 if (source_filename)
2773 Args->push_back(source_filename);
2774
2775 // Do we need the detailed preprocessing record?
2776 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2777 Args->push_back("-Xclang");
2778 Args->push_back("-detailed-preprocessing-record");
2779 }
2780
2781 unsigned NumErrors = Diags->getClient()->getNumErrors();
2782 OwningPtr<ASTUnit> ErrUnit;
2783 OwningPtr<ASTUnit> Unit(
2784 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2785 /* vector::data() not portable */,
2786 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2787 Diags,
2788 CXXIdx->getClangResourcesPath(),
2789 CXXIdx->getOnlyLocalDecls(),
2790 /*CaptureDiagnostics=*/true,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002791 *RemappedFiles.get(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002792 /*RemappedFilesKeepOriginalName=*/true,
2793 PrecompilePreamble,
2794 TUKind,
Alp Toker8c8a8752013-12-03 06:53:35 +00002795 CacheCodeCompletionResults,
Guy Benyei11169dd2012-12-18 14:30:41 +00002796 IncludeBriefCommentsInCodeCompletion,
2797 /*AllowPCHWithCompilerErrors=*/true,
2798 SkipFunctionBodies,
2799 /*UserFilesAreVolatile=*/true,
2800 ForSerialization,
2801 &ErrUnit));
2802
2803 if (NumErrors != Diags->getClient()->getNumErrors()) {
2804 // Make sure to check that 'Unit' is non-NULL.
2805 if (CXXIdx->getDisplayDiagnostics())
2806 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2807 }
2808
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002809 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2810 PTUI->result = CXError_ASTReadError;
2811 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002812 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002813 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2814 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002815}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002816
2817CXTranslationUnit
2818clang_parseTranslationUnit(CXIndex CIdx,
2819 const char *source_filename,
2820 const char *const *command_line_args,
2821 int num_command_line_args,
2822 struct CXUnsavedFile *unsaved_files,
2823 unsigned num_unsaved_files,
2824 unsigned options) {
2825 CXTranslationUnit TU;
2826 enum CXErrorCode Result = clang_parseTranslationUnit2(
2827 CIdx, source_filename, command_line_args, num_command_line_args,
2828 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002829 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002830 assert((TU && Result == CXError_Success) ||
2831 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002832 return TU;
2833}
2834
2835enum CXErrorCode clang_parseTranslationUnit2(
2836 CXIndex CIdx,
2837 const char *source_filename,
2838 const char *const *command_line_args,
2839 int num_command_line_args,
2840 struct CXUnsavedFile *unsaved_files,
2841 unsigned num_unsaved_files,
2842 unsigned options,
2843 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002844 LOG_FUNC_SECTION {
2845 *Log << source_filename << ": ";
2846 for (int i = 0; i != num_command_line_args; ++i)
2847 *Log << command_line_args[i] << " ";
2848 }
2849
Guy Benyei11169dd2012-12-18 14:30:41 +00002850 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2851 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002852 num_unsaved_files, options, out_TU,
2853 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002854 llvm::CrashRecoveryContext CRC;
2855
2856 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2857 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2858 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2859 fprintf(stderr, " 'command_line_args' : [");
2860 for (int i = 0; i != num_command_line_args; ++i) {
2861 if (i)
2862 fprintf(stderr, ", ");
2863 fprintf(stderr, "'%s'", command_line_args[i]);
2864 }
2865 fprintf(stderr, "],\n");
2866 fprintf(stderr, " 'unsaved_files' : [");
2867 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2868 if (i)
2869 fprintf(stderr, ", ");
2870 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2871 unsaved_files[i].Length);
2872 }
2873 fprintf(stderr, "],\n");
2874 fprintf(stderr, " 'options' : %d,\n", options);
2875 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002876
2877 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002878 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002879 if (CXTranslationUnit *TU = PTUI.out_TU)
2880 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002881 }
2882
2883 return PTUI.result;
2884}
2885
2886unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2887 return CXSaveTranslationUnit_None;
2888}
2889
2890namespace {
2891
2892struct SaveTranslationUnitInfo {
2893 CXTranslationUnit TU;
2894 const char *FileName;
2895 unsigned options;
2896 CXSaveError result;
2897};
2898
2899}
2900
2901static void clang_saveTranslationUnit_Impl(void *UserData) {
2902 SaveTranslationUnitInfo *STUI =
2903 static_cast<SaveTranslationUnitInfo*>(UserData);
2904
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002905 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002906 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2907 setThreadBackgroundPriority();
2908
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002909 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002910 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2911}
2912
2913int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2914 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002915 LOG_FUNC_SECTION {
2916 *Log << TU << ' ' << FileName;
2917 }
2918
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002919 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002920 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002921 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002922 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002923
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002924 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002925 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2926 if (!CXXUnit->hasSema())
2927 return CXSaveError_InvalidTU;
2928
2929 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2930
2931 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2932 getenv("LIBCLANG_NOTHREADS")) {
2933 clang_saveTranslationUnit_Impl(&STUI);
2934
2935 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2936 PrintLibclangResourceUsage(TU);
2937
2938 return STUI.result;
2939 }
2940
2941 // We have an AST that has invalid nodes due to compiler errors.
2942 // Use a crash recovery thread for protection.
2943
2944 llvm::CrashRecoveryContext CRC;
2945
2946 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2947 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2948 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2949 fprintf(stderr, " 'options' : %d,\n", options);
2950 fprintf(stderr, "}\n");
2951
2952 return CXSaveError_Unknown;
2953
2954 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2955 PrintLibclangResourceUsage(TU);
2956 }
2957
2958 return STUI.result;
2959}
2960
2961void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2962 if (CTUnit) {
2963 // If the translation unit has been marked as unsafe to free, just discard
2964 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002965 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2966 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002967 return;
2968
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002969 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002970 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002971 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2972 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002973 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002974 delete CTUnit;
2975 }
2976}
2977
2978unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2979 return CXReparse_None;
2980}
2981
2982struct ReparseTranslationUnitInfo {
2983 CXTranslationUnit TU;
2984 unsigned num_unsaved_files;
2985 struct CXUnsavedFile *unsaved_files;
2986 unsigned options;
2987 int result;
2988};
2989
2990static void clang_reparseTranslationUnit_Impl(void *UserData) {
2991 ReparseTranslationUnitInfo *RTUI =
2992 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002993 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002994
Guy Benyei11169dd2012-12-18 14:30:41 +00002995 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002996 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2997 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2998 unsigned options = RTUI->options;
2999 (void) options;
3000
3001 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003002 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003003 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003004 RTUI->result = CXError_InvalidArguments;
3005 return;
3006 }
3007 if (unsaved_files == NULL && num_unsaved_files != 0) {
3008 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003009 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003010 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003011
3012 // Reset the associated diagnostics.
3013 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3014 TU->Diagnostics = 0;
3015
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003016 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003017 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3018 setThreadBackgroundPriority();
3019
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003020 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003021 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3022
3023 OwningPtr<std::vector<ASTUnit::RemappedFile> >
3024 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
3025
3026 // Recover resources if we crash before exiting this function.
3027 llvm::CrashRecoveryContextCleanupRegistrar<
3028 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3029
3030 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3031 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3032 const llvm::MemoryBuffer *Buffer
3033 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3034 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3035 Buffer));
3036 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003037
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003038 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003039 RTUI->result = CXError_Success;
3040 else if (isASTReadError(CXXUnit))
3041 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003042}
3043
3044int clang_reparseTranslationUnit(CXTranslationUnit TU,
3045 unsigned num_unsaved_files,
3046 struct CXUnsavedFile *unsaved_files,
3047 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003048 LOG_FUNC_SECTION {
3049 *Log << TU;
3050 }
3051
Guy Benyei11169dd2012-12-18 14:30:41 +00003052 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003053 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003054
3055 if (getenv("LIBCLANG_NOTHREADS")) {
3056 clang_reparseTranslationUnit_Impl(&RTUI);
3057 return RTUI.result;
3058 }
3059
3060 llvm::CrashRecoveryContext CRC;
3061
3062 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3063 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003064 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003065 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003066 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3067 PrintLibclangResourceUsage(TU);
3068
3069 return RTUI.result;
3070}
3071
3072
3073CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003074 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003075 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003076 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003077 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003078
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003079 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003080 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003081}
3082
3083CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003084 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003085 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003086 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003087 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003088
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003089 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003090 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3091}
3092
3093} // end: extern "C"
3094
3095//===----------------------------------------------------------------------===//
3096// CXFile Operations.
3097//===----------------------------------------------------------------------===//
3098
3099extern "C" {
3100CXString clang_getFileName(CXFile SFile) {
3101 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003102 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003103
3104 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003105 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003106}
3107
3108time_t clang_getFileTime(CXFile SFile) {
3109 if (!SFile)
3110 return 0;
3111
3112 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3113 return FEnt->getModificationTime();
3114}
3115
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003116CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003117 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003118 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003119 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003120 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003121
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003122 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003123
3124 FileManager &FMgr = CXXUnit->getFileManager();
3125 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3126}
3127
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003128unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3129 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003130 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003131 LOG_BAD_TU(TU);
3132 return 0;
3133 }
3134
3135 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003136 return 0;
3137
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003138 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003139 FileEntry *FEnt = static_cast<FileEntry *>(file);
3140 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3141 .isFileMultipleIncludeGuarded(FEnt);
3142}
3143
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003144int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3145 if (!file || !outID)
3146 return 1;
3147
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003148 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003149 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3150 outID->data[0] = ID.getDevice();
3151 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003152 outID->data[2] = FEnt->getModificationTime();
3153 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003154}
3155
Guy Benyei11169dd2012-12-18 14:30:41 +00003156} // end: extern "C"
3157
3158//===----------------------------------------------------------------------===//
3159// CXCursor Operations.
3160//===----------------------------------------------------------------------===//
3161
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003162static const Decl *getDeclFromExpr(const Stmt *E) {
3163 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003164 return getDeclFromExpr(CE->getSubExpr());
3165
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003166 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003167 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003168 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003169 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003170 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003171 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003172 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003173 if (PRE->isExplicitProperty())
3174 return PRE->getExplicitProperty();
3175 // It could be messaging both getter and setter as in:
3176 // ++myobj.myprop;
3177 // in which case prefer to associate the setter since it is less obvious
3178 // from inspecting the source that the setter is going to get called.
3179 if (PRE->isMessagingSetter())
3180 return PRE->getImplicitPropertySetter();
3181 return PRE->getImplicitPropertyGetter();
3182 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003183 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003184 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003185 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003186 if (Expr *Src = OVE->getSourceExpr())
3187 return getDeclFromExpr(Src);
3188
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003189 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003190 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003191 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003192 if (!CE->isElidable())
3193 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003194 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003195 return OME->getMethodDecl();
3196
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003197 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003198 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003199 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003200 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3201 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003202 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003203 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3204 isa<ParmVarDecl>(SizeOfPack->getPack()))
3205 return SizeOfPack->getPack();
3206
3207 return 0;
3208}
3209
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003210static SourceLocation getLocationFromExpr(const Expr *E) {
3211 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003212 return getLocationFromExpr(CE->getSubExpr());
3213
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003214 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003215 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003216 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003217 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003218 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003219 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003220 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003221 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003222 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003223 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003224 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003225 return PropRef->getLocation();
3226
3227 return E->getLocStart();
3228}
3229
3230extern "C" {
3231
3232unsigned clang_visitChildren(CXCursor parent,
3233 CXCursorVisitor visitor,
3234 CXClientData client_data) {
3235 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3236 /*VisitPreprocessorLast=*/false);
3237 return CursorVis.VisitChildren(parent);
3238}
3239
3240#ifndef __has_feature
3241#define __has_feature(x) 0
3242#endif
3243#if __has_feature(blocks)
3244typedef enum CXChildVisitResult
3245 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3246
3247static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3248 CXClientData client_data) {
3249 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3250 return block(cursor, parent);
3251}
3252#else
3253// If we are compiled with a compiler that doesn't have native blocks support,
3254// define and call the block manually, so the
3255typedef struct _CXChildVisitResult
3256{
3257 void *isa;
3258 int flags;
3259 int reserved;
3260 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3261 CXCursor);
3262} *CXCursorVisitorBlock;
3263
3264static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3265 CXClientData client_data) {
3266 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3267 return block->invoke(block, cursor, parent);
3268}
3269#endif
3270
3271
3272unsigned clang_visitChildrenWithBlock(CXCursor parent,
3273 CXCursorVisitorBlock block) {
3274 return clang_visitChildren(parent, visitWithBlock, block);
3275}
3276
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003277static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003278 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003279 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003280
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003281 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003282 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003283 if (const ObjCPropertyImplDecl *PropImpl =
3284 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003285 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003286 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003287
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003288 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003289 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003290 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003291
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003292 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003293 }
3294
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003295 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003296 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003297
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003298 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003299 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3300 // and returns different names. NamedDecl returns the class name and
3301 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003302 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003303
3304 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003305 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003306
3307 SmallString<1024> S;
3308 llvm::raw_svector_ostream os(S);
3309 ND->printName(os);
3310
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003311 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003312}
3313
3314CXString clang_getCursorSpelling(CXCursor C) {
3315 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003316 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003317
3318 if (clang_isReference(C.kind)) {
3319 switch (C.kind) {
3320 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003321 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003322 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003323 }
3324 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003325 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003326 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003327 }
3328 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003329 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003330 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003331 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003332 }
3333 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003334 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003335 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003336 }
3337 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003338 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003339 assert(Type && "Missing type decl");
3340
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003341 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003342 getAsString());
3343 }
3344 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003345 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003346 assert(Template && "Missing template decl");
3347
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003348 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 }
3350
3351 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003352 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003353 assert(NS && "Missing namespace decl");
3354
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003355 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003356 }
3357
3358 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003359 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003360 assert(Field && "Missing member decl");
3361
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003362 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003363 }
3364
3365 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003366 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003367 assert(Label && "Missing label");
3368
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003369 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003370 }
3371
3372 case CXCursor_OverloadedDeclRef: {
3373 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003374 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3375 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003376 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003377 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003379 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003380 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003381 OverloadedTemplateStorage *Ovl
3382 = Storage.get<OverloadedTemplateStorage*>();
3383 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003384 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003385 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003386 }
3387
3388 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003389 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003390 assert(Var && "Missing variable decl");
3391
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003392 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003393 }
3394
3395 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003396 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003397 }
3398 }
3399
3400 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003401 const Expr *E = getCursorExpr(C);
3402
3403 if (C.kind == CXCursor_ObjCStringLiteral ||
3404 C.kind == CXCursor_StringLiteral) {
3405 const StringLiteral *SLit;
3406 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3407 SLit = OSL->getString();
3408 } else {
3409 SLit = cast<StringLiteral>(E);
3410 }
3411 SmallString<256> Buf;
3412 llvm::raw_svector_ostream OS(Buf);
3413 SLit->outputString(OS);
3414 return cxstring::createDup(OS.str());
3415 }
3416
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003417 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003418 if (D)
3419 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003420 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003421 }
3422
3423 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003424 const Stmt *S = getCursorStmt(C);
3425 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003426 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003427
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003428 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003429 }
3430
3431 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003432 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003433 ->getNameStart());
3434
3435 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003436 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003437 ->getNameStart());
3438
3439 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003440 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003441
3442 if (clang_isDeclaration(C.kind))
3443 return getDeclSpelling(getCursorDecl(C));
3444
3445 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003446 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003447 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003448 }
3449
3450 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003451 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003452 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003453 }
3454
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003455 if (C.kind == CXCursor_PackedAttr) {
3456 return cxstring::createRef("packed");
3457 }
3458
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003459 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003460}
3461
3462CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3463 unsigned pieceIndex,
3464 unsigned options) {
3465 if (clang_Cursor_isNull(C))
3466 return clang_getNullRange();
3467
3468 ASTContext &Ctx = getCursorContext(C);
3469
3470 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003471 const Stmt *S = getCursorStmt(C);
3472 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003473 if (pieceIndex > 0)
3474 return clang_getNullRange();
3475 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3476 }
3477
3478 return clang_getNullRange();
3479 }
3480
3481 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003482 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003483 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3484 if (pieceIndex >= ME->getNumSelectorLocs())
3485 return clang_getNullRange();
3486 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3487 }
3488 }
3489
3490 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3491 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003492 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003493 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3494 if (pieceIndex >= MD->getNumSelectorLocs())
3495 return clang_getNullRange();
3496 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3497 }
3498 }
3499
3500 if (C.kind == CXCursor_ObjCCategoryDecl ||
3501 C.kind == CXCursor_ObjCCategoryImplDecl) {
3502 if (pieceIndex > 0)
3503 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003504 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003505 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3506 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003507 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003508 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3509 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3510 }
3511
3512 if (C.kind == CXCursor_ModuleImportDecl) {
3513 if (pieceIndex > 0)
3514 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003515 if (const ImportDecl *ImportD =
3516 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003517 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3518 if (!Locs.empty())
3519 return cxloc::translateSourceRange(Ctx,
3520 SourceRange(Locs.front(), Locs.back()));
3521 }
3522 return clang_getNullRange();
3523 }
3524
3525 // FIXME: A CXCursor_InclusionDirective should give the location of the
3526 // filename, but we don't keep track of this.
3527
3528 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3529 // but we don't keep track of this.
3530
3531 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3532 // but we don't keep track of this.
3533
3534 // Default handling, give the location of the cursor.
3535
3536 if (pieceIndex > 0)
3537 return clang_getNullRange();
3538
3539 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3540 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3541 return cxloc::translateSourceRange(Ctx, Loc);
3542}
3543
3544CXString clang_getCursorDisplayName(CXCursor C) {
3545 if (!clang_isDeclaration(C.kind))
3546 return clang_getCursorSpelling(C);
3547
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003548 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003550 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003551
3552 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003553 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003554 D = FunTmpl->getTemplatedDecl();
3555
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003556 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003557 SmallString<64> Str;
3558 llvm::raw_svector_ostream OS(Str);
3559 OS << *Function;
3560 if (Function->getPrimaryTemplate())
3561 OS << "<>";
3562 OS << "(";
3563 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3564 if (I)
3565 OS << ", ";
3566 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3567 }
3568
3569 if (Function->isVariadic()) {
3570 if (Function->getNumParams())
3571 OS << ", ";
3572 OS << "...";
3573 }
3574 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003575 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003576 }
3577
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003578 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003579 SmallString<64> Str;
3580 llvm::raw_svector_ostream OS(Str);
3581 OS << *ClassTemplate;
3582 OS << "<";
3583 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3584 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3585 if (I)
3586 OS << ", ";
3587
3588 NamedDecl *Param = Params->getParam(I);
3589 if (Param->getIdentifier()) {
3590 OS << Param->getIdentifier()->getName();
3591 continue;
3592 }
3593
3594 // There is no parameter name, which makes this tricky. Try to come up
3595 // with something useful that isn't too long.
3596 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3597 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3598 else if (NonTypeTemplateParmDecl *NTTP
3599 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3600 OS << NTTP->getType().getAsString(Policy);
3601 else
3602 OS << "template<...> class";
3603 }
3604
3605 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003606 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003607 }
3608
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003609 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3611 // If the type was explicitly written, use that.
3612 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003613 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003614
Benjamin Kramer9170e912013-02-22 15:46:01 +00003615 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003616 llvm::raw_svector_ostream OS(Str);
3617 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003618 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003619 ClassSpec->getTemplateArgs().data(),
3620 ClassSpec->getTemplateArgs().size(),
3621 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003622 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 }
3624
3625 return clang_getCursorSpelling(C);
3626}
3627
3628CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3629 switch (Kind) {
3630 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003631 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003632 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003633 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003635 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003637 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003641 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003643 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003645 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003647 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003651 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003653 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003655 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003659 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003663 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003665 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003673 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003758 case CXCursor_ObjCSelfExpr:
3759 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003876 case CXCursor_PackedAttr:
3877 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003926 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003927 return cxstring::createRef("OMPParallelDirective");
3928 case CXCursor_OMPSimdDirective:
3929 return cxstring::createRef("OMPSimdDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 }
3931
3932 llvm_unreachable("Unhandled CXCursorKind");
3933}
3934
3935struct GetCursorData {
3936 SourceLocation TokenBeginLoc;
3937 bool PointsAtMacroArgExpansion;
3938 bool VisitedObjCPropertyImplDecl;
3939 SourceLocation VisitedDeclaratorDeclStartLoc;
3940 CXCursor &BestCursor;
3941
3942 GetCursorData(SourceManager &SM,
3943 SourceLocation tokenBegin, CXCursor &outputCursor)
3944 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3945 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3946 VisitedObjCPropertyImplDecl = false;
3947 }
3948};
3949
3950static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3951 CXCursor parent,
3952 CXClientData client_data) {
3953 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3954 CXCursor *BestCursor = &Data->BestCursor;
3955
3956 // If we point inside a macro argument we should provide info of what the
3957 // token is so use the actual cursor, don't replace it with a macro expansion
3958 // cursor.
3959 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3960 return CXChildVisit_Recurse;
3961
3962 if (clang_isDeclaration(cursor.kind)) {
3963 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003964 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3966 if (MD->isImplicit())
3967 return CXChildVisit_Break;
3968
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003969 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3971 // Check that when we have multiple @class references in the same line,
3972 // that later ones do not override the previous ones.
3973 // If we have:
3974 // @class Foo, Bar;
3975 // source ranges for both start at '@', so 'Bar' will end up overriding
3976 // 'Foo' even though the cursor location was at 'Foo'.
3977 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3978 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003979 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3981 if (PrevID != ID &&
3982 !PrevID->isThisDeclarationADefinition() &&
3983 !ID->isThisDeclarationADefinition())
3984 return CXChildVisit_Break;
3985 }
3986
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003987 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3989 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3990 // Check that when we have multiple declarators in the same line,
3991 // that later ones do not override the previous ones.
3992 // If we have:
3993 // int Foo, Bar;
3994 // source ranges for both start at 'int', so 'Bar' will end up overriding
3995 // 'Foo' even though the cursor location was at 'Foo'.
3996 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3997 return CXChildVisit_Break;
3998 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3999
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004000 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4002 (void)PropImp;
4003 // Check that when we have multiple @synthesize in the same line,
4004 // that later ones do not override the previous ones.
4005 // If we have:
4006 // @synthesize Foo, Bar;
4007 // source ranges for both start at '@', so 'Bar' will end up overriding
4008 // 'Foo' even though the cursor location was at 'Foo'.
4009 if (Data->VisitedObjCPropertyImplDecl)
4010 return CXChildVisit_Break;
4011 Data->VisitedObjCPropertyImplDecl = true;
4012 }
4013 }
4014
4015 if (clang_isExpression(cursor.kind) &&
4016 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004017 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 // Avoid having the cursor of an expression replace the declaration cursor
4019 // when the expression source range overlaps the declaration range.
4020 // This can happen for C++ constructor expressions whose range generally
4021 // include the variable declaration, e.g.:
4022 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4023 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4024 D->getLocation() == Data->TokenBeginLoc)
4025 return CXChildVisit_Break;
4026 }
4027 }
4028
4029 // If our current best cursor is the construction of a temporary object,
4030 // don't replace that cursor with a type reference, because we want
4031 // clang_getCursor() to point at the constructor.
4032 if (clang_isExpression(BestCursor->kind) &&
4033 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4034 cursor.kind == CXCursor_TypeRef) {
4035 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4036 // as having the actual point on the type reference.
4037 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4038 return CXChildVisit_Recurse;
4039 }
4040
4041 *BestCursor = cursor;
4042 return CXChildVisit_Recurse;
4043}
4044
4045CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004046 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004047 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004049 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004050
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004051 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4053
4054 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4055 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4056
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004057 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 CXFile SearchFile;
4059 unsigned SearchLine, SearchColumn;
4060 CXFile ResultFile;
4061 unsigned ResultLine, ResultColumn;
4062 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4063 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4064 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4065
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004066 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4067 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 &ResultColumn, 0);
4069 SearchFileName = clang_getFileName(SearchFile);
4070 ResultFileName = clang_getFileName(ResultFile);
4071 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4072 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004073 *Log << llvm::format("(%s:%d:%d) = %s",
4074 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4075 clang_getCString(KindSpelling))
4076 << llvm::format("(%s:%d:%d):%s%s",
4077 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4078 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 clang_disposeString(SearchFileName);
4080 clang_disposeString(ResultFileName);
4081 clang_disposeString(KindSpelling);
4082 clang_disposeString(USR);
4083
4084 CXCursor Definition = clang_getCursorDefinition(Result);
4085 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4086 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4087 CXString DefinitionKindSpelling
4088 = clang_getCursorKindSpelling(Definition.kind);
4089 CXFile DefinitionFile;
4090 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004091 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 &DefinitionLine, &DefinitionColumn, 0);
4093 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004094 *Log << llvm::format(" -> %s(%s:%d:%d)",
4095 clang_getCString(DefinitionKindSpelling),
4096 clang_getCString(DefinitionFileName),
4097 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 clang_disposeString(DefinitionFileName);
4099 clang_disposeString(DefinitionKindSpelling);
4100 }
4101 }
4102
4103 return Result;
4104}
4105
4106CXCursor clang_getNullCursor(void) {
4107 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4108}
4109
4110unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004111 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4112 // can't set consistently. For example, when visiting a DeclStmt we will set
4113 // it but we don't set it on the result of clang_getCursorDefinition for
4114 // a reference of the same declaration.
4115 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4116 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4117 // to provide that kind of info.
4118 if (clang_isDeclaration(X.kind))
4119 X.data[1] = 0;
4120 if (clang_isDeclaration(Y.kind))
4121 Y.data[1] = 0;
4122
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 return X == Y;
4124}
4125
4126unsigned clang_hashCursor(CXCursor C) {
4127 unsigned Index = 0;
4128 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4129 Index = 1;
4130
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004131 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 std::make_pair(C.kind, C.data[Index]));
4133}
4134
4135unsigned clang_isInvalid(enum CXCursorKind K) {
4136 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4137}
4138
4139unsigned clang_isDeclaration(enum CXCursorKind K) {
4140 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4141 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4142}
4143
4144unsigned clang_isReference(enum CXCursorKind K) {
4145 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4146}
4147
4148unsigned clang_isExpression(enum CXCursorKind K) {
4149 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4150}
4151
4152unsigned clang_isStatement(enum CXCursorKind K) {
4153 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4154}
4155
4156unsigned clang_isAttribute(enum CXCursorKind K) {
4157 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4158}
4159
4160unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4161 return K == CXCursor_TranslationUnit;
4162}
4163
4164unsigned clang_isPreprocessing(enum CXCursorKind K) {
4165 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4166}
4167
4168unsigned clang_isUnexposed(enum CXCursorKind K) {
4169 switch (K) {
4170 case CXCursor_UnexposedDecl:
4171 case CXCursor_UnexposedExpr:
4172 case CXCursor_UnexposedStmt:
4173 case CXCursor_UnexposedAttr:
4174 return true;
4175 default:
4176 return false;
4177 }
4178}
4179
4180CXCursorKind clang_getCursorKind(CXCursor C) {
4181 return C.kind;
4182}
4183
4184CXSourceLocation clang_getCursorLocation(CXCursor C) {
4185 if (clang_isReference(C.kind)) {
4186 switch (C.kind) {
4187 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004188 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 = getCursorObjCSuperClassRef(C);
4190 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4191 }
4192
4193 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004194 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 = getCursorObjCProtocolRef(C);
4196 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4197 }
4198
4199 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004200 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 = getCursorObjCClassRef(C);
4202 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4203 }
4204
4205 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004206 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4208 }
4209
4210 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004211 std::pair<const TemplateDecl *, SourceLocation> P =
4212 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004213 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4214 }
4215
4216 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004217 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4219 }
4220
4221 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004222 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004223 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4224 }
4225
4226 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004227 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004228 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4229 }
4230
4231 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004232 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004233 if (!BaseSpec)
4234 return clang_getNullLocation();
4235
4236 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4237 return cxloc::translateSourceLocation(getCursorContext(C),
4238 TSInfo->getTypeLoc().getBeginLoc());
4239
4240 return cxloc::translateSourceLocation(getCursorContext(C),
4241 BaseSpec->getLocStart());
4242 }
4243
4244 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004245 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004246 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4247 }
4248
4249 case CXCursor_OverloadedDeclRef:
4250 return cxloc::translateSourceLocation(getCursorContext(C),
4251 getCursorOverloadedDeclRef(C).second);
4252
4253 default:
4254 // FIXME: Need a way to enumerate all non-reference cases.
4255 llvm_unreachable("Missed a reference kind");
4256 }
4257 }
4258
4259 if (clang_isExpression(C.kind))
4260 return cxloc::translateSourceLocation(getCursorContext(C),
4261 getLocationFromExpr(getCursorExpr(C)));
4262
4263 if (clang_isStatement(C.kind))
4264 return cxloc::translateSourceLocation(getCursorContext(C),
4265 getCursorStmt(C)->getLocStart());
4266
4267 if (C.kind == CXCursor_PreprocessingDirective) {
4268 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4269 return cxloc::translateSourceLocation(getCursorContext(C), L);
4270 }
4271
4272 if (C.kind == CXCursor_MacroExpansion) {
4273 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004274 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004275 return cxloc::translateSourceLocation(getCursorContext(C), L);
4276 }
4277
4278 if (C.kind == CXCursor_MacroDefinition) {
4279 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4280 return cxloc::translateSourceLocation(getCursorContext(C), L);
4281 }
4282
4283 if (C.kind == CXCursor_InclusionDirective) {
4284 SourceLocation L
4285 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4286 return cxloc::translateSourceLocation(getCursorContext(C), L);
4287 }
4288
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004289 if (clang_isAttribute(C.kind)) {
4290 SourceLocation L
4291 = cxcursor::getCursorAttr(C)->getLocation();
4292 return cxloc::translateSourceLocation(getCursorContext(C), L);
4293 }
4294
Guy Benyei11169dd2012-12-18 14:30:41 +00004295 if (!clang_isDeclaration(C.kind))
4296 return clang_getNullLocation();
4297
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004298 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004299 if (!D)
4300 return clang_getNullLocation();
4301
4302 SourceLocation Loc = D->getLocation();
4303 // FIXME: Multiple variables declared in a single declaration
4304 // currently lack the information needed to correctly determine their
4305 // ranges when accounting for the type-specifier. We use context
4306 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4307 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004308 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004309 if (!cxcursor::isFirstInDeclGroup(C))
4310 Loc = VD->getLocation();
4311 }
4312
4313 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004314 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004315 Loc = MD->getSelectorStartLoc();
4316
4317 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4318}
4319
4320} // end extern "C"
4321
4322CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4323 assert(TU);
4324
4325 // Guard against an invalid SourceLocation, or we may assert in one
4326 // of the following calls.
4327 if (SLoc.isInvalid())
4328 return clang_getNullCursor();
4329
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004330 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004331
4332 // Translate the given source location to make it point at the beginning of
4333 // the token under the cursor.
4334 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4335 CXXUnit->getASTContext().getLangOpts());
4336
4337 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4338 if (SLoc.isValid()) {
4339 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4340 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4341 /*VisitPreprocessorLast=*/true,
4342 /*VisitIncludedEntities=*/false,
4343 SourceLocation(SLoc));
4344 CursorVis.visitFileRegion();
4345 }
4346
4347 return Result;
4348}
4349
4350static SourceRange getRawCursorExtent(CXCursor C) {
4351 if (clang_isReference(C.kind)) {
4352 switch (C.kind) {
4353 case CXCursor_ObjCSuperClassRef:
4354 return getCursorObjCSuperClassRef(C).second;
4355
4356 case CXCursor_ObjCProtocolRef:
4357 return getCursorObjCProtocolRef(C).second;
4358
4359 case CXCursor_ObjCClassRef:
4360 return getCursorObjCClassRef(C).second;
4361
4362 case CXCursor_TypeRef:
4363 return getCursorTypeRef(C).second;
4364
4365 case CXCursor_TemplateRef:
4366 return getCursorTemplateRef(C).second;
4367
4368 case CXCursor_NamespaceRef:
4369 return getCursorNamespaceRef(C).second;
4370
4371 case CXCursor_MemberRef:
4372 return getCursorMemberRef(C).second;
4373
4374 case CXCursor_CXXBaseSpecifier:
4375 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4376
4377 case CXCursor_LabelRef:
4378 return getCursorLabelRef(C).second;
4379
4380 case CXCursor_OverloadedDeclRef:
4381 return getCursorOverloadedDeclRef(C).second;
4382
4383 case CXCursor_VariableRef:
4384 return getCursorVariableRef(C).second;
4385
4386 default:
4387 // FIXME: Need a way to enumerate all non-reference cases.
4388 llvm_unreachable("Missed a reference kind");
4389 }
4390 }
4391
4392 if (clang_isExpression(C.kind))
4393 return getCursorExpr(C)->getSourceRange();
4394
4395 if (clang_isStatement(C.kind))
4396 return getCursorStmt(C)->getSourceRange();
4397
4398 if (clang_isAttribute(C.kind))
4399 return getCursorAttr(C)->getRange();
4400
4401 if (C.kind == CXCursor_PreprocessingDirective)
4402 return cxcursor::getCursorPreprocessingDirective(C);
4403
4404 if (C.kind == CXCursor_MacroExpansion) {
4405 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004406 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004407 return TU->mapRangeFromPreamble(Range);
4408 }
4409
4410 if (C.kind == CXCursor_MacroDefinition) {
4411 ASTUnit *TU = getCursorASTUnit(C);
4412 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4413 return TU->mapRangeFromPreamble(Range);
4414 }
4415
4416 if (C.kind == CXCursor_InclusionDirective) {
4417 ASTUnit *TU = getCursorASTUnit(C);
4418 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4419 return TU->mapRangeFromPreamble(Range);
4420 }
4421
4422 if (C.kind == CXCursor_TranslationUnit) {
4423 ASTUnit *TU = getCursorASTUnit(C);
4424 FileID MainID = TU->getSourceManager().getMainFileID();
4425 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4426 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4427 return SourceRange(Start, End);
4428 }
4429
4430 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004431 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004432 if (!D)
4433 return SourceRange();
4434
4435 SourceRange R = D->getSourceRange();
4436 // FIXME: Multiple variables declared in a single declaration
4437 // currently lack the information needed to correctly determine their
4438 // ranges when accounting for the type-specifier. We use context
4439 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4440 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004441 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004442 if (!cxcursor::isFirstInDeclGroup(C))
4443 R.setBegin(VD->getLocation());
4444 }
4445 return R;
4446 }
4447 return SourceRange();
4448}
4449
4450/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4451/// the decl-specifier-seq for declarations.
4452static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4453 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004454 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004455 if (!D)
4456 return SourceRange();
4457
4458 SourceRange R = D->getSourceRange();
4459
4460 // Adjust the start of the location for declarations preceded by
4461 // declaration specifiers.
4462 SourceLocation StartLoc;
4463 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4464 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4465 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004466 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004467 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4468 StartLoc = TI->getTypeLoc().getLocStart();
4469 }
4470
4471 if (StartLoc.isValid() && R.getBegin().isValid() &&
4472 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4473 R.setBegin(StartLoc);
4474
4475 // FIXME: Multiple variables declared in a single declaration
4476 // currently lack the information needed to correctly determine their
4477 // ranges when accounting for the type-specifier. We use context
4478 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4479 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004480 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004481 if (!cxcursor::isFirstInDeclGroup(C))
4482 R.setBegin(VD->getLocation());
4483 }
4484
4485 return R;
4486 }
4487
4488 return getRawCursorExtent(C);
4489}
4490
4491extern "C" {
4492
4493CXSourceRange clang_getCursorExtent(CXCursor C) {
4494 SourceRange R = getRawCursorExtent(C);
4495 if (R.isInvalid())
4496 return clang_getNullRange();
4497
4498 return cxloc::translateSourceRange(getCursorContext(C), R);
4499}
4500
4501CXCursor clang_getCursorReferenced(CXCursor C) {
4502 if (clang_isInvalid(C.kind))
4503 return clang_getNullCursor();
4504
4505 CXTranslationUnit tu = getCursorTU(C);
4506 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004507 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004508 if (!D)
4509 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004510 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004511 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004512 if (const ObjCPropertyImplDecl *PropImpl =
4513 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004514 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4515 return MakeCXCursor(Property, tu);
4516
4517 return C;
4518 }
4519
4520 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004521 const Expr *E = getCursorExpr(C);
4522 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004523 if (D) {
4524 CXCursor declCursor = MakeCXCursor(D, tu);
4525 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4526 declCursor);
4527 return declCursor;
4528 }
4529
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004530 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004531 return MakeCursorOverloadedDeclRef(Ovl, tu);
4532
4533 return clang_getNullCursor();
4534 }
4535
4536 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004537 const Stmt *S = getCursorStmt(C);
4538 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004539 if (LabelDecl *label = Goto->getLabel())
4540 if (LabelStmt *labelS = label->getStmt())
4541 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4542
4543 return clang_getNullCursor();
4544 }
4545
4546 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004547 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004548 return MakeMacroDefinitionCursor(Def, tu);
4549 }
4550
4551 if (!clang_isReference(C.kind))
4552 return clang_getNullCursor();
4553
4554 switch (C.kind) {
4555 case CXCursor_ObjCSuperClassRef:
4556 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4557
4558 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004559 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4560 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 return MakeCXCursor(Def, tu);
4562
4563 return MakeCXCursor(Prot, tu);
4564 }
4565
4566 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004567 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4568 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004569 return MakeCXCursor(Def, tu);
4570
4571 return MakeCXCursor(Class, tu);
4572 }
4573
4574 case CXCursor_TypeRef:
4575 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4576
4577 case CXCursor_TemplateRef:
4578 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4579
4580 case CXCursor_NamespaceRef:
4581 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4582
4583 case CXCursor_MemberRef:
4584 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4585
4586 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004587 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004588 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4589 tu ));
4590 }
4591
4592 case CXCursor_LabelRef:
4593 // FIXME: We end up faking the "parent" declaration here because we
4594 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004595 return MakeCXCursor(getCursorLabelRef(C).first,
4596 cxtu::getASTUnit(tu)->getASTContext()
4597 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004598 tu);
4599
4600 case CXCursor_OverloadedDeclRef:
4601 return C;
4602
4603 case CXCursor_VariableRef:
4604 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4605
4606 default:
4607 // We would prefer to enumerate all non-reference cursor kinds here.
4608 llvm_unreachable("Unhandled reference cursor kind");
4609 }
4610}
4611
4612CXCursor clang_getCursorDefinition(CXCursor C) {
4613 if (clang_isInvalid(C.kind))
4614 return clang_getNullCursor();
4615
4616 CXTranslationUnit TU = getCursorTU(C);
4617
4618 bool WasReference = false;
4619 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4620 C = clang_getCursorReferenced(C);
4621 WasReference = true;
4622 }
4623
4624 if (C.kind == CXCursor_MacroExpansion)
4625 return clang_getCursorReferenced(C);
4626
4627 if (!clang_isDeclaration(C.kind))
4628 return clang_getNullCursor();
4629
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004630 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 if (!D)
4632 return clang_getNullCursor();
4633
4634 switch (D->getKind()) {
4635 // Declaration kinds that don't really separate the notions of
4636 // declaration and definition.
4637 case Decl::Namespace:
4638 case Decl::Typedef:
4639 case Decl::TypeAlias:
4640 case Decl::TypeAliasTemplate:
4641 case Decl::TemplateTypeParm:
4642 case Decl::EnumConstant:
4643 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004644 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 case Decl::IndirectField:
4646 case Decl::ObjCIvar:
4647 case Decl::ObjCAtDefsField:
4648 case Decl::ImplicitParam:
4649 case Decl::ParmVar:
4650 case Decl::NonTypeTemplateParm:
4651 case Decl::TemplateTemplateParm:
4652 case Decl::ObjCCategoryImpl:
4653 case Decl::ObjCImplementation:
4654 case Decl::AccessSpec:
4655 case Decl::LinkageSpec:
4656 case Decl::ObjCPropertyImpl:
4657 case Decl::FileScopeAsm:
4658 case Decl::StaticAssert:
4659 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004660 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 case Decl::Label: // FIXME: Is this right??
4662 case Decl::ClassScopeFunctionSpecialization:
4663 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004664 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 return C;
4666
4667 // Declaration kinds that don't make any sense here, but are
4668 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004669 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004670 case Decl::TranslationUnit:
4671 break;
4672
4673 // Declaration kinds for which the definition is not resolvable.
4674 case Decl::UnresolvedUsingTypename:
4675 case Decl::UnresolvedUsingValue:
4676 break;
4677
4678 case Decl::UsingDirective:
4679 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4680 TU);
4681
4682 case Decl::NamespaceAlias:
4683 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4684
4685 case Decl::Enum:
4686 case Decl::Record:
4687 case Decl::CXXRecord:
4688 case Decl::ClassTemplateSpecialization:
4689 case Decl::ClassTemplatePartialSpecialization:
4690 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4691 return MakeCXCursor(Def, TU);
4692 return clang_getNullCursor();
4693
4694 case Decl::Function:
4695 case Decl::CXXMethod:
4696 case Decl::CXXConstructor:
4697 case Decl::CXXDestructor:
4698 case Decl::CXXConversion: {
4699 const FunctionDecl *Def = 0;
4700 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004701 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004702 return clang_getNullCursor();
4703 }
4704
Larisse Voufo39a1e502013-08-06 01:03:05 +00004705 case Decl::Var:
4706 case Decl::VarTemplateSpecialization:
4707 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004708 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004709 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004710 return MakeCXCursor(Def, TU);
4711 return clang_getNullCursor();
4712 }
4713
4714 case Decl::FunctionTemplate: {
4715 const FunctionDecl *Def = 0;
4716 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4717 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4718 return clang_getNullCursor();
4719 }
4720
4721 case Decl::ClassTemplate: {
4722 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4723 ->getDefinition())
4724 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4725 TU);
4726 return clang_getNullCursor();
4727 }
4728
Larisse Voufo39a1e502013-08-06 01:03:05 +00004729 case Decl::VarTemplate: {
4730 if (VarDecl *Def =
4731 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4732 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4733 return clang_getNullCursor();
4734 }
4735
Guy Benyei11169dd2012-12-18 14:30:41 +00004736 case Decl::Using:
4737 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4738 D->getLocation(), TU);
4739
4740 case Decl::UsingShadow:
4741 return clang_getCursorDefinition(
4742 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4743 TU));
4744
4745 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004746 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004747 if (Method->isThisDeclarationADefinition())
4748 return C;
4749
4750 // Dig out the method definition in the associated
4751 // @implementation, if we have it.
4752 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004753 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004754 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4755 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4756 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4757 Method->isInstanceMethod()))
4758 if (Def->isThisDeclarationADefinition())
4759 return MakeCXCursor(Def, TU);
4760
4761 return clang_getNullCursor();
4762 }
4763
4764 case Decl::ObjCCategory:
4765 if (ObjCCategoryImplDecl *Impl
4766 = cast<ObjCCategoryDecl>(D)->getImplementation())
4767 return MakeCXCursor(Impl, TU);
4768 return clang_getNullCursor();
4769
4770 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004771 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004772 return MakeCXCursor(Def, TU);
4773 return clang_getNullCursor();
4774
4775 case Decl::ObjCInterface: {
4776 // There are two notions of a "definition" for an Objective-C
4777 // class: the interface and its implementation. When we resolved a
4778 // reference to an Objective-C class, produce the @interface as
4779 // the definition; when we were provided with the interface,
4780 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004781 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004782 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004783 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004784 return MakeCXCursor(Def, TU);
4785 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4786 return MakeCXCursor(Impl, TU);
4787 return clang_getNullCursor();
4788 }
4789
4790 case Decl::ObjCProperty:
4791 // FIXME: We don't really know where to find the
4792 // ObjCPropertyImplDecls that implement this property.
4793 return clang_getNullCursor();
4794
4795 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004796 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004797 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004798 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004799 return MakeCXCursor(Def, TU);
4800
4801 return clang_getNullCursor();
4802
4803 case Decl::Friend:
4804 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4805 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4806 return clang_getNullCursor();
4807
4808 case Decl::FriendTemplate:
4809 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4810 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4811 return clang_getNullCursor();
4812 }
4813
4814 return clang_getNullCursor();
4815}
4816
4817unsigned clang_isCursorDefinition(CXCursor C) {
4818 if (!clang_isDeclaration(C.kind))
4819 return 0;
4820
4821 return clang_getCursorDefinition(C) == C;
4822}
4823
4824CXCursor clang_getCanonicalCursor(CXCursor C) {
4825 if (!clang_isDeclaration(C.kind))
4826 return C;
4827
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004828 if (const Decl *D = getCursorDecl(C)) {
4829 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004830 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4831 return MakeCXCursor(CatD, getCursorTU(C));
4832
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004833 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4834 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004835 return MakeCXCursor(IFD, getCursorTU(C));
4836
4837 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4838 }
4839
4840 return C;
4841}
4842
4843int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4844 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4845}
4846
4847unsigned clang_getNumOverloadedDecls(CXCursor C) {
4848 if (C.kind != CXCursor_OverloadedDeclRef)
4849 return 0;
4850
4851 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004852 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004853 return E->getNumDecls();
4854
4855 if (OverloadedTemplateStorage *S
4856 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4857 return S->size();
4858
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004859 const Decl *D = Storage.get<const Decl *>();
4860 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004861 return Using->shadow_size();
4862
4863 return 0;
4864}
4865
4866CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4867 if (cursor.kind != CXCursor_OverloadedDeclRef)
4868 return clang_getNullCursor();
4869
4870 if (index >= clang_getNumOverloadedDecls(cursor))
4871 return clang_getNullCursor();
4872
4873 CXTranslationUnit TU = getCursorTU(cursor);
4874 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004875 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004876 return MakeCXCursor(E->decls_begin()[index], TU);
4877
4878 if (OverloadedTemplateStorage *S
4879 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4880 return MakeCXCursor(S->begin()[index], TU);
4881
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004882 const Decl *D = Storage.get<const Decl *>();
4883 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004884 // FIXME: This is, unfortunately, linear time.
4885 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4886 std::advance(Pos, index);
4887 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4888 }
4889
4890 return clang_getNullCursor();
4891}
4892
4893void clang_getDefinitionSpellingAndExtent(CXCursor C,
4894 const char **startBuf,
4895 const char **endBuf,
4896 unsigned *startLine,
4897 unsigned *startColumn,
4898 unsigned *endLine,
4899 unsigned *endColumn) {
4900 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004901 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004902 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4903
4904 SourceManager &SM = FD->getASTContext().getSourceManager();
4905 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4906 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4907 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4908 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4909 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4910 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4911}
4912
4913
4914CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4915 unsigned PieceIndex) {
4916 RefNamePieces Pieces;
4917
4918 switch (C.kind) {
4919 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004920 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004921 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4922 E->getQualifierLoc().getSourceRange());
4923 break;
4924
4925 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004926 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004927 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4928 E->getQualifierLoc().getSourceRange(),
4929 E->getOptionalExplicitTemplateArgs());
4930 break;
4931
4932 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004933 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004934 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004935 const Expr *Callee = OCE->getCallee();
4936 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004937 Callee = ICE->getSubExpr();
4938
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004939 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004940 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4941 DRE->getQualifierLoc().getSourceRange());
4942 }
4943 break;
4944
4945 default:
4946 break;
4947 }
4948
4949 if (Pieces.empty()) {
4950 if (PieceIndex == 0)
4951 return clang_getCursorExtent(C);
4952 } else if (PieceIndex < Pieces.size()) {
4953 SourceRange R = Pieces[PieceIndex];
4954 if (R.isValid())
4955 return cxloc::translateSourceRange(getCursorContext(C), R);
4956 }
4957
4958 return clang_getNullRange();
4959}
4960
4961void clang_enableStackTraces(void) {
4962 llvm::sys::PrintStackTraceOnErrorSignal();
4963}
4964
4965void clang_executeOnThread(void (*fn)(void*), void *user_data,
4966 unsigned stack_size) {
4967 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4968}
4969
4970} // end: extern "C"
4971
4972//===----------------------------------------------------------------------===//
4973// Token-based Operations.
4974//===----------------------------------------------------------------------===//
4975
4976/* CXToken layout:
4977 * int_data[0]: a CXTokenKind
4978 * int_data[1]: starting token location
4979 * int_data[2]: token length
4980 * int_data[3]: reserved
4981 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4982 * otherwise unused.
4983 */
4984extern "C" {
4985
4986CXTokenKind clang_getTokenKind(CXToken CXTok) {
4987 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4988}
4989
4990CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4991 switch (clang_getTokenKind(CXTok)) {
4992 case CXToken_Identifier:
4993 case CXToken_Keyword:
4994 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004995 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004996 ->getNameStart());
4997
4998 case CXToken_Literal: {
4999 // We have stashed the starting pointer in the ptr_data field. Use it.
5000 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005001 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005002 }
5003
5004 case CXToken_Punctuation:
5005 case CXToken_Comment:
5006 break;
5007 }
5008
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005009 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005010 LOG_BAD_TU(TU);
5011 return cxstring::createEmpty();
5012 }
5013
Guy Benyei11169dd2012-12-18 14:30:41 +00005014 // We have to find the starting buffer pointer the hard way, by
5015 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005016 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005017 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005018 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005019
5020 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5021 std::pair<FileID, unsigned> LocInfo
5022 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5023 bool Invalid = false;
5024 StringRef Buffer
5025 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5026 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005027 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005028
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005029 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005030}
5031
5032CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005033 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005034 LOG_BAD_TU(TU);
5035 return clang_getNullLocation();
5036 }
5037
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005038 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005039 if (!CXXUnit)
5040 return clang_getNullLocation();
5041
5042 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5043 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5044}
5045
5046CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005047 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005048 LOG_BAD_TU(TU);
5049 return clang_getNullRange();
5050 }
5051
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005052 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005053 if (!CXXUnit)
5054 return clang_getNullRange();
5055
5056 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5057 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5058}
5059
5060static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5061 SmallVectorImpl<CXToken> &CXTokens) {
5062 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5063 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005064 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005065 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005066 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005067
5068 // Cannot tokenize across files.
5069 if (BeginLocInfo.first != EndLocInfo.first)
5070 return;
5071
5072 // Create a lexer
5073 bool Invalid = false;
5074 StringRef Buffer
5075 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5076 if (Invalid)
5077 return;
5078
5079 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5080 CXXUnit->getASTContext().getLangOpts(),
5081 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5082 Lex.SetCommentRetentionState(true);
5083
5084 // Lex tokens until we hit the end of the range.
5085 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5086 Token Tok;
5087 bool previousWasAt = false;
5088 do {
5089 // Lex the next token
5090 Lex.LexFromRawLexer(Tok);
5091 if (Tok.is(tok::eof))
5092 break;
5093
5094 // Initialize the CXToken.
5095 CXToken CXTok;
5096
5097 // - Common fields
5098 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5099 CXTok.int_data[2] = Tok.getLength();
5100 CXTok.int_data[3] = 0;
5101
5102 // - Kind-specific fields
5103 if (Tok.isLiteral()) {
5104 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005105 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005106 } else if (Tok.is(tok::raw_identifier)) {
5107 // Lookup the identifier to determine whether we have a keyword.
5108 IdentifierInfo *II
5109 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5110
5111 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5112 CXTok.int_data[0] = CXToken_Keyword;
5113 }
5114 else {
5115 CXTok.int_data[0] = Tok.is(tok::identifier)
5116 ? CXToken_Identifier
5117 : CXToken_Keyword;
5118 }
5119 CXTok.ptr_data = II;
5120 } else if (Tok.is(tok::comment)) {
5121 CXTok.int_data[0] = CXToken_Comment;
5122 CXTok.ptr_data = 0;
5123 } else {
5124 CXTok.int_data[0] = CXToken_Punctuation;
5125 CXTok.ptr_data = 0;
5126 }
5127 CXTokens.push_back(CXTok);
5128 previousWasAt = Tok.is(tok::at);
5129 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5130}
5131
5132void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5133 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005134 LOG_FUNC_SECTION {
5135 *Log << TU << ' ' << Range;
5136 }
5137
Guy Benyei11169dd2012-12-18 14:30:41 +00005138 if (Tokens)
5139 *Tokens = 0;
5140 if (NumTokens)
5141 *NumTokens = 0;
5142
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005143 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005144 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005145 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005146 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005147
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005148 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005149 if (!CXXUnit || !Tokens || !NumTokens)
5150 return;
5151
5152 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5153
5154 SourceRange R = cxloc::translateCXSourceRange(Range);
5155 if (R.isInvalid())
5156 return;
5157
5158 SmallVector<CXToken, 32> CXTokens;
5159 getTokens(CXXUnit, R, CXTokens);
5160
5161 if (CXTokens.empty())
5162 return;
5163
5164 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5165 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5166 *NumTokens = CXTokens.size();
5167}
5168
5169void clang_disposeTokens(CXTranslationUnit TU,
5170 CXToken *Tokens, unsigned NumTokens) {
5171 free(Tokens);
5172}
5173
5174} // end: extern "C"
5175
5176//===----------------------------------------------------------------------===//
5177// Token annotation APIs.
5178//===----------------------------------------------------------------------===//
5179
Guy Benyei11169dd2012-12-18 14:30:41 +00005180static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5181 CXCursor parent,
5182 CXClientData client_data);
5183static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5184 CXClientData client_data);
5185
5186namespace {
5187class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005188 CXToken *Tokens;
5189 CXCursor *Cursors;
5190 unsigned NumTokens;
5191 unsigned TokIdx;
5192 unsigned PreprocessingTokIdx;
5193 CursorVisitor AnnotateVis;
5194 SourceManager &SrcMgr;
5195 bool HasContextSensitiveKeywords;
5196
5197 struct PostChildrenInfo {
5198 CXCursor Cursor;
5199 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005200 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005201 unsigned BeforeChildrenTokenIdx;
5202 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005203 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005204
5205 CXToken &getTok(unsigned Idx) {
5206 assert(Idx < NumTokens);
5207 return Tokens[Idx];
5208 }
5209 const CXToken &getTok(unsigned Idx) const {
5210 assert(Idx < NumTokens);
5211 return Tokens[Idx];
5212 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005213 bool MoreTokens() const { return TokIdx < NumTokens; }
5214 unsigned NextToken() const { return TokIdx; }
5215 void AdvanceToken() { ++TokIdx; }
5216 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005217 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 }
5219 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005220 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005221 }
5222 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005223 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 }
5225
5226 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005227 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 SourceRange);
5229
5230public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005231 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005232 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005233 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005234 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005235 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005236 AnnotateTokensVisitor, this,
5237 /*VisitPreprocessorLast=*/true,
5238 /*VisitIncludedEntities=*/false,
5239 RegionOfInterest,
5240 /*VisitDeclsOnly=*/false,
5241 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005242 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005243 HasContextSensitiveKeywords(false) { }
5244
5245 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5246 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5247 bool postVisitChildren(CXCursor cursor);
5248 void AnnotateTokens();
5249
5250 /// \brief Determine whether the annotator saw any cursors that have
5251 /// context-sensitive keywords.
5252 bool hasContextSensitiveKeywords() const {
5253 return HasContextSensitiveKeywords;
5254 }
5255
5256 ~AnnotateTokensWorker() {
5257 assert(PostChildrenInfos.empty());
5258 }
5259};
5260}
5261
5262void AnnotateTokensWorker::AnnotateTokens() {
5263 // Walk the AST within the region of interest, annotating tokens
5264 // along the way.
5265 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005266}
Guy Benyei11169dd2012-12-18 14:30:41 +00005267
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005268static inline void updateCursorAnnotation(CXCursor &Cursor,
5269 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005270 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005271 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005272 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005273}
5274
5275/// \brief It annotates and advances tokens with a cursor until the comparison
5276//// between the cursor location and the source range is the same as
5277/// \arg compResult.
5278///
5279/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5280/// Pass RangeOverlap to annotate tokens inside a range.
5281void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5282 RangeComparisonResult compResult,
5283 SourceRange range) {
5284 while (MoreTokens()) {
5285 const unsigned I = NextToken();
5286 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005287 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5288 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005289
5290 SourceLocation TokLoc = GetTokenLoc(I);
5291 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005292 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005293 AdvanceToken();
5294 continue;
5295 }
5296 break;
5297 }
5298}
5299
5300/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005301/// \returns true if it advanced beyond all macro tokens, false otherwise.
5302bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005303 CXCursor updateC,
5304 RangeComparisonResult compResult,
5305 SourceRange range) {
5306 assert(MoreTokens());
5307 assert(isFunctionMacroToken(NextToken()) &&
5308 "Should be called only for macro arg tokens");
5309
5310 // This works differently than annotateAndAdvanceTokens; because expanded
5311 // macro arguments can have arbitrary translation-unit source order, we do not
5312 // advance the token index one by one until a token fails the range test.
5313 // We only advance once past all of the macro arg tokens if all of them
5314 // pass the range test. If one of them fails we keep the token index pointing
5315 // at the start of the macro arg tokens so that the failing token will be
5316 // annotated by a subsequent annotation try.
5317
5318 bool atLeastOneCompFail = false;
5319
5320 unsigned I = NextToken();
5321 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5322 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5323 if (TokLoc.isFileID())
5324 continue; // not macro arg token, it's parens or comma.
5325 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5326 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5327 Cursors[I] = updateC;
5328 } else
5329 atLeastOneCompFail = true;
5330 }
5331
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005332 if (atLeastOneCompFail)
5333 return false;
5334
5335 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5336 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005337}
5338
5339enum CXChildVisitResult
5340AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005341 SourceRange cursorRange = getRawCursorExtent(cursor);
5342 if (cursorRange.isInvalid())
5343 return CXChildVisit_Recurse;
5344
5345 if (!HasContextSensitiveKeywords) {
5346 // Objective-C properties can have context-sensitive keywords.
5347 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005348 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005349 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5350 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5351 }
5352 // Objective-C methods can have context-sensitive keywords.
5353 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5354 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005355 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005356 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5357 if (Method->getObjCDeclQualifier())
5358 HasContextSensitiveKeywords = true;
5359 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005360 for (const auto *P : Method->params()) {
5361 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005362 HasContextSensitiveKeywords = true;
5363 break;
5364 }
5365 }
5366 }
5367 }
5368 }
5369 // C++ methods can have context-sensitive keywords.
5370 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005371 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005372 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5373 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5374 HasContextSensitiveKeywords = true;
5375 }
5376 }
5377 // C++ classes can have context-sensitive keywords.
5378 else if (cursor.kind == CXCursor_StructDecl ||
5379 cursor.kind == CXCursor_ClassDecl ||
5380 cursor.kind == CXCursor_ClassTemplate ||
5381 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005382 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005383 if (D->hasAttr<FinalAttr>())
5384 HasContextSensitiveKeywords = true;
5385 }
5386 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005387
5388 // Don't override a property annotation with its getter/setter method.
5389 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5390 parent.kind == CXCursor_ObjCPropertyDecl)
5391 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005392
5393 if (clang_isPreprocessing(cursor.kind)) {
5394 // Items in the preprocessing record are kept separate from items in
5395 // declarations, so we keep a separate token index.
5396 unsigned SavedTokIdx = TokIdx;
5397 TokIdx = PreprocessingTokIdx;
5398
5399 // Skip tokens up until we catch up to the beginning of the preprocessing
5400 // entry.
5401 while (MoreTokens()) {
5402 const unsigned I = NextToken();
5403 SourceLocation TokLoc = GetTokenLoc(I);
5404 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5405 case RangeBefore:
5406 AdvanceToken();
5407 continue;
5408 case RangeAfter:
5409 case RangeOverlap:
5410 break;
5411 }
5412 break;
5413 }
5414
5415 // Look at all of the tokens within this range.
5416 while (MoreTokens()) {
5417 const unsigned I = NextToken();
5418 SourceLocation TokLoc = GetTokenLoc(I);
5419 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5420 case RangeBefore:
5421 llvm_unreachable("Infeasible");
5422 case RangeAfter:
5423 break;
5424 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005425 // For macro expansions, just note where the beginning of the macro
5426 // expansion occurs.
5427 if (cursor.kind == CXCursor_MacroExpansion) {
5428 if (TokLoc == cursorRange.getBegin())
5429 Cursors[I] = cursor;
5430 AdvanceToken();
5431 break;
5432 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005433 // We may have already annotated macro names inside macro definitions.
5434 if (Cursors[I].kind != CXCursor_MacroExpansion)
5435 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005436 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005437 continue;
5438 }
5439 break;
5440 }
5441
5442 // Save the preprocessing token index; restore the non-preprocessing
5443 // token index.
5444 PreprocessingTokIdx = TokIdx;
5445 TokIdx = SavedTokIdx;
5446 return CXChildVisit_Recurse;
5447 }
5448
5449 if (cursorRange.isInvalid())
5450 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005451
5452 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005453 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005454 const enum CXCursorKind K = clang_getCursorKind(parent);
5455 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005456 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5457 // Attributes are annotated out-of-order, skip tokens until we reach it.
5458 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005459 ? clang_getNullCursor() : parent;
5460
5461 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5462
5463 // Avoid having the cursor of an expression "overwrite" the annotation of the
5464 // variable declaration that it belongs to.
5465 // This can happen for C++ constructor expressions whose range generally
5466 // include the variable declaration, e.g.:
5467 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005468 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005469 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005470 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005471 const unsigned I = NextToken();
5472 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5473 E->getLocStart() == D->getLocation() &&
5474 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005475 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005476 AdvanceToken();
5477 }
5478 }
5479 }
5480
5481 // Before recursing into the children keep some state that we are going
5482 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5483 // extra work after the child nodes are visited.
5484 // Note that we don't call VisitChildren here to avoid traversing statements
5485 // code-recursively which can blow the stack.
5486
5487 PostChildrenInfo Info;
5488 Info.Cursor = cursor;
5489 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005490 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005491 Info.BeforeChildrenTokenIdx = NextToken();
5492 PostChildrenInfos.push_back(Info);
5493
5494 return CXChildVisit_Recurse;
5495}
5496
5497bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5498 if (PostChildrenInfos.empty())
5499 return false;
5500 const PostChildrenInfo &Info = PostChildrenInfos.back();
5501 if (!clang_equalCursors(Info.Cursor, cursor))
5502 return false;
5503
5504 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5505 const unsigned AfterChildren = NextToken();
5506 SourceRange cursorRange = Info.CursorRange;
5507
5508 // Scan the tokens that are at the end of the cursor, but are not captured
5509 // but the child cursors.
5510 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5511
5512 // Scan the tokens that are at the beginning of the cursor, but are not
5513 // capture by the child cursors.
5514 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5515 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5516 break;
5517
5518 Cursors[I] = cursor;
5519 }
5520
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005521 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5522 // encountered the attribute cursor.
5523 if (clang_isAttribute(cursor.kind))
5524 TokIdx = Info.BeforeReachingCursorIdx;
5525
Guy Benyei11169dd2012-12-18 14:30:41 +00005526 PostChildrenInfos.pop_back();
5527 return false;
5528}
5529
5530static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5531 CXCursor parent,
5532 CXClientData client_data) {
5533 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5534}
5535
5536static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5537 CXClientData client_data) {
5538 return static_cast<AnnotateTokensWorker*>(client_data)->
5539 postVisitChildren(cursor);
5540}
5541
5542namespace {
5543
5544/// \brief Uses the macro expansions in the preprocessing record to find
5545/// and mark tokens that are macro arguments. This info is used by the
5546/// AnnotateTokensWorker.
5547class MarkMacroArgTokensVisitor {
5548 SourceManager &SM;
5549 CXToken *Tokens;
5550 unsigned NumTokens;
5551 unsigned CurIdx;
5552
5553public:
5554 MarkMacroArgTokensVisitor(SourceManager &SM,
5555 CXToken *tokens, unsigned numTokens)
5556 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5557
5558 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5559 if (cursor.kind != CXCursor_MacroExpansion)
5560 return CXChildVisit_Continue;
5561
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005562 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005563 if (macroRange.getBegin() == macroRange.getEnd())
5564 return CXChildVisit_Continue; // it's not a function macro.
5565
5566 for (; CurIdx < NumTokens; ++CurIdx) {
5567 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5568 macroRange.getBegin()))
5569 break;
5570 }
5571
5572 if (CurIdx == NumTokens)
5573 return CXChildVisit_Break;
5574
5575 for (; CurIdx < NumTokens; ++CurIdx) {
5576 SourceLocation tokLoc = getTokenLoc(CurIdx);
5577 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5578 break;
5579
5580 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5581 }
5582
5583 if (CurIdx == NumTokens)
5584 return CXChildVisit_Break;
5585
5586 return CXChildVisit_Continue;
5587 }
5588
5589private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005590 CXToken &getTok(unsigned Idx) {
5591 assert(Idx < NumTokens);
5592 return Tokens[Idx];
5593 }
5594 const CXToken &getTok(unsigned Idx) const {
5595 assert(Idx < NumTokens);
5596 return Tokens[Idx];
5597 }
5598
Guy Benyei11169dd2012-12-18 14:30:41 +00005599 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005600 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005601 }
5602
5603 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5604 // The third field is reserved and currently not used. Use it here
5605 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005606 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005607 }
5608};
5609
5610} // end anonymous namespace
5611
5612static CXChildVisitResult
5613MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5614 CXClientData client_data) {
5615 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5616 parent);
5617}
5618
5619namespace {
5620 struct clang_annotateTokens_Data {
5621 CXTranslationUnit TU;
5622 ASTUnit *CXXUnit;
5623 CXToken *Tokens;
5624 unsigned NumTokens;
5625 CXCursor *Cursors;
5626 };
5627}
5628
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005629/// \brief Used by \c annotatePreprocessorTokens.
5630/// \returns true if lexing was finished, false otherwise.
5631static bool lexNext(Lexer &Lex, Token &Tok,
5632 unsigned &NextIdx, unsigned NumTokens) {
5633 if (NextIdx >= NumTokens)
5634 return true;
5635
5636 ++NextIdx;
5637 Lex.LexFromRawLexer(Tok);
5638 if (Tok.is(tok::eof))
5639 return true;
5640
5641 return false;
5642}
5643
Guy Benyei11169dd2012-12-18 14:30:41 +00005644static void annotatePreprocessorTokens(CXTranslationUnit TU,
5645 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005646 CXCursor *Cursors,
5647 CXToken *Tokens,
5648 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005649 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005650
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005651 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005652 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5653 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005654 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005655 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005656 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005657
5658 if (BeginLocInfo.first != EndLocInfo.first)
5659 return;
5660
5661 StringRef Buffer;
5662 bool Invalid = false;
5663 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5664 if (Buffer.empty() || Invalid)
5665 return;
5666
5667 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5668 CXXUnit->getASTContext().getLangOpts(),
5669 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5670 Buffer.end());
5671 Lex.SetCommentRetentionState(true);
5672
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005673 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005674 // Lex tokens in raw mode until we hit the end of the range, to avoid
5675 // entering #includes or expanding macros.
5676 while (true) {
5677 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005678 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5679 break;
5680 unsigned TokIdx = NextIdx-1;
5681 assert(Tok.getLocation() ==
5682 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005683
5684 reprocess:
5685 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005686 // We have found a preprocessing directive. Annotate the tokens
5687 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005688 //
5689 // FIXME: Some simple tests here could identify macro definitions and
5690 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005691
5692 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005693 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5694 break;
5695
5696 MacroInfo *MI = 0;
5697 if (Tok.is(tok::raw_identifier) &&
5698 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5699 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5700 break;
5701
5702 if (Tok.is(tok::raw_identifier)) {
5703 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5704 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5705 SourceLocation MappedTokLoc =
5706 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5707 MI = getMacroInfo(II, MappedTokLoc, TU);
5708 }
5709 }
5710
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005711 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005712 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005713 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5714 finished = true;
5715 break;
5716 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005717 // If we are in a macro definition, check if the token was ever a
5718 // macro name and annotate it if that's the case.
5719 if (MI) {
5720 SourceLocation SaveLoc = Tok.getLocation();
5721 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5722 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5723 Tok.setLocation(SaveLoc);
5724 if (MacroDef)
5725 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5726 Tok.getLocation(), TU);
5727 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005728 } while (!Tok.isAtStartOfLine());
5729
5730 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5731 assert(TokIdx <= LastIdx);
5732 SourceLocation EndLoc =
5733 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5734 CXCursor Cursor =
5735 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5736
5737 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005738 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005739
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005740 if (finished)
5741 break;
5742 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005743 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005744 }
5745}
5746
5747// This gets run a separate thread to avoid stack blowout.
5748static void clang_annotateTokensImpl(void *UserData) {
5749 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5750 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5751 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5752 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5753 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5754
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005755 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005756 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5757 setThreadBackgroundPriority();
5758
5759 // Determine the region of interest, which contains all of the tokens.
5760 SourceRange RegionOfInterest;
5761 RegionOfInterest.setBegin(
5762 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5763 RegionOfInterest.setEnd(
5764 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5765 Tokens[NumTokens-1])));
5766
Guy Benyei11169dd2012-12-18 14:30:41 +00005767 // Relex the tokens within the source range to look for preprocessing
5768 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005769 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005770
5771 // If begin location points inside a macro argument, set it to the expansion
5772 // location so we can have the full context when annotating semantically.
5773 {
5774 SourceManager &SM = CXXUnit->getSourceManager();
5775 SourceLocation Loc =
5776 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5777 if (Loc.isMacroID())
5778 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5779 }
5780
Guy Benyei11169dd2012-12-18 14:30:41 +00005781 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5782 // Search and mark tokens that are macro argument expansions.
5783 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5784 Tokens, NumTokens);
5785 CursorVisitor MacroArgMarker(TU,
5786 MarkMacroArgTokensVisitorDelegate, &Visitor,
5787 /*VisitPreprocessorLast=*/true,
5788 /*VisitIncludedEntities=*/false,
5789 RegionOfInterest);
5790 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5791 }
5792
5793 // Annotate all of the source locations in the region of interest that map to
5794 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005795 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005796
5797 // FIXME: We use a ridiculous stack size here because the data-recursion
5798 // algorithm uses a large stack frame than the non-data recursive version,
5799 // and AnnotationTokensWorker currently transforms the data-recursion
5800 // algorithm back into a traditional recursion by explicitly calling
5801 // VisitChildren(). We will need to remove this explicit recursive call.
5802 W.AnnotateTokens();
5803
5804 // If we ran into any entities that involve context-sensitive keywords,
5805 // take another pass through the tokens to mark them as such.
5806 if (W.hasContextSensitiveKeywords()) {
5807 for (unsigned I = 0; I != NumTokens; ++I) {
5808 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5809 continue;
5810
5811 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5812 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005813 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005814 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5815 if (Property->getPropertyAttributesAsWritten() != 0 &&
5816 llvm::StringSwitch<bool>(II->getName())
5817 .Case("readonly", true)
5818 .Case("assign", true)
5819 .Case("unsafe_unretained", true)
5820 .Case("readwrite", true)
5821 .Case("retain", true)
5822 .Case("copy", true)
5823 .Case("nonatomic", true)
5824 .Case("atomic", true)
5825 .Case("getter", true)
5826 .Case("setter", true)
5827 .Case("strong", true)
5828 .Case("weak", true)
5829 .Default(false))
5830 Tokens[I].int_data[0] = CXToken_Keyword;
5831 }
5832 continue;
5833 }
5834
5835 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5836 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5837 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5838 if (llvm::StringSwitch<bool>(II->getName())
5839 .Case("in", true)
5840 .Case("out", true)
5841 .Case("inout", true)
5842 .Case("oneway", true)
5843 .Case("bycopy", true)
5844 .Case("byref", true)
5845 .Default(false))
5846 Tokens[I].int_data[0] = CXToken_Keyword;
5847 continue;
5848 }
5849
5850 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5851 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5852 Tokens[I].int_data[0] = CXToken_Keyword;
5853 continue;
5854 }
5855 }
5856 }
5857}
5858
5859extern "C" {
5860
5861void clang_annotateTokens(CXTranslationUnit TU,
5862 CXToken *Tokens, unsigned NumTokens,
5863 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005864 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005865 LOG_BAD_TU(TU);
5866 return;
5867 }
5868 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005869 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005870 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005871 }
5872
5873 LOG_FUNC_SECTION {
5874 *Log << TU << ' ';
5875 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5876 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5877 *Log << clang_getRange(bloc, eloc);
5878 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005879
5880 // Any token we don't specifically annotate will have a NULL cursor.
5881 CXCursor C = clang_getNullCursor();
5882 for (unsigned I = 0; I != NumTokens; ++I)
5883 Cursors[I] = C;
5884
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005885 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005886 if (!CXXUnit)
5887 return;
5888
5889 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5890
5891 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5892 llvm::CrashRecoveryContext CRC;
5893 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5894 GetSafetyThreadStackSize() * 2)) {
5895 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5896 }
5897}
5898
5899} // end: extern "C"
5900
5901//===----------------------------------------------------------------------===//
5902// Operations for querying linkage of a cursor.
5903//===----------------------------------------------------------------------===//
5904
5905extern "C" {
5906CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5907 if (!clang_isDeclaration(cursor.kind))
5908 return CXLinkage_Invalid;
5909
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005910 const Decl *D = cxcursor::getCursorDecl(cursor);
5911 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005912 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005913 case NoLinkage:
5914 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005915 case InternalLinkage: return CXLinkage_Internal;
5916 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5917 case ExternalLinkage: return CXLinkage_External;
5918 };
5919
5920 return CXLinkage_Invalid;
5921}
5922} // end: extern "C"
5923
5924//===----------------------------------------------------------------------===//
5925// Operations for querying language of a cursor.
5926//===----------------------------------------------------------------------===//
5927
5928static CXLanguageKind getDeclLanguage(const Decl *D) {
5929 if (!D)
5930 return CXLanguage_C;
5931
5932 switch (D->getKind()) {
5933 default:
5934 break;
5935 case Decl::ImplicitParam:
5936 case Decl::ObjCAtDefsField:
5937 case Decl::ObjCCategory:
5938 case Decl::ObjCCategoryImpl:
5939 case Decl::ObjCCompatibleAlias:
5940 case Decl::ObjCImplementation:
5941 case Decl::ObjCInterface:
5942 case Decl::ObjCIvar:
5943 case Decl::ObjCMethod:
5944 case Decl::ObjCProperty:
5945 case Decl::ObjCPropertyImpl:
5946 case Decl::ObjCProtocol:
5947 return CXLanguage_ObjC;
5948 case Decl::CXXConstructor:
5949 case Decl::CXXConversion:
5950 case Decl::CXXDestructor:
5951 case Decl::CXXMethod:
5952 case Decl::CXXRecord:
5953 case Decl::ClassTemplate:
5954 case Decl::ClassTemplatePartialSpecialization:
5955 case Decl::ClassTemplateSpecialization:
5956 case Decl::Friend:
5957 case Decl::FriendTemplate:
5958 case Decl::FunctionTemplate:
5959 case Decl::LinkageSpec:
5960 case Decl::Namespace:
5961 case Decl::NamespaceAlias:
5962 case Decl::NonTypeTemplateParm:
5963 case Decl::StaticAssert:
5964 case Decl::TemplateTemplateParm:
5965 case Decl::TemplateTypeParm:
5966 case Decl::UnresolvedUsingTypename:
5967 case Decl::UnresolvedUsingValue:
5968 case Decl::Using:
5969 case Decl::UsingDirective:
5970 case Decl::UsingShadow:
5971 return CXLanguage_CPlusPlus;
5972 }
5973
5974 return CXLanguage_C;
5975}
5976
5977extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005978
5979static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5980 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5981 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005982
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005983 switch (D->getAvailability()) {
5984 case AR_Available:
5985 case AR_NotYetIntroduced:
5986 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005987 return getCursorAvailabilityForDecl(
5988 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005989 return CXAvailability_Available;
5990
5991 case AR_Deprecated:
5992 return CXAvailability_Deprecated;
5993
5994 case AR_Unavailable:
5995 return CXAvailability_NotAvailable;
5996 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005997
5998 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005999}
6000
Guy Benyei11169dd2012-12-18 14:30:41 +00006001enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6002 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006003 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6004 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006005
6006 return CXAvailability_Available;
6007}
6008
6009static CXVersion convertVersion(VersionTuple In) {
6010 CXVersion Out = { -1, -1, -1 };
6011 if (In.empty())
6012 return Out;
6013
6014 Out.Major = In.getMajor();
6015
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006016 Optional<unsigned> Minor = In.getMinor();
6017 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006018 Out.Minor = *Minor;
6019 else
6020 return Out;
6021
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006022 Optional<unsigned> Subminor = In.getSubminor();
6023 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006024 Out.Subminor = *Subminor;
6025
6026 return Out;
6027}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006028
6029static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6030 int *always_deprecated,
6031 CXString *deprecated_message,
6032 int *always_unavailable,
6033 CXString *unavailable_message,
6034 CXPlatformAvailability *availability,
6035 int availability_size) {
6036 bool HadAvailAttr = false;
6037 int N = 0;
Aaron Ballman7dce1a82014-03-07 13:13:38 +00006038 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
6039 ++A) {
6040 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006041 HadAvailAttr = true;
6042 if (always_deprecated)
6043 *always_deprecated = 1;
6044 if (deprecated_message)
6045 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
6046 continue;
6047 }
6048
Aaron Ballman7dce1a82014-03-07 13:13:38 +00006049 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006050 HadAvailAttr = true;
6051 if (always_unavailable)
6052 *always_unavailable = 1;
6053 if (unavailable_message) {
6054 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6055 }
6056 continue;
6057 }
6058
Aaron Ballman7dce1a82014-03-07 13:13:38 +00006059 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006060 HadAvailAttr = true;
6061 if (N < availability_size) {
6062 availability[N].Platform
6063 = cxstring::createDup(Avail->getPlatform()->getName());
6064 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6065 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6066 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6067 availability[N].Unavailable = Avail->getUnavailable();
6068 availability[N].Message = cxstring::createDup(Avail->getMessage());
6069 }
6070 ++N;
6071 }
6072 }
6073
6074 if (!HadAvailAttr)
6075 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6076 return getCursorPlatformAvailabilityForDecl(
6077 cast<Decl>(EnumConst->getDeclContext()),
6078 always_deprecated,
6079 deprecated_message,
6080 always_unavailable,
6081 unavailable_message,
6082 availability,
6083 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006084
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006085 return N;
6086}
6087
Guy Benyei11169dd2012-12-18 14:30:41 +00006088int clang_getCursorPlatformAvailability(CXCursor cursor,
6089 int *always_deprecated,
6090 CXString *deprecated_message,
6091 int *always_unavailable,
6092 CXString *unavailable_message,
6093 CXPlatformAvailability *availability,
6094 int availability_size) {
6095 if (always_deprecated)
6096 *always_deprecated = 0;
6097 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006098 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006099 if (always_unavailable)
6100 *always_unavailable = 0;
6101 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006102 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006103
Guy Benyei11169dd2012-12-18 14:30:41 +00006104 if (!clang_isDeclaration(cursor.kind))
6105 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006106
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006107 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006108 if (!D)
6109 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006110
6111 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6112 deprecated_message,
6113 always_unavailable,
6114 unavailable_message,
6115 availability,
6116 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006117}
6118
6119void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6120 clang_disposeString(availability->Platform);
6121 clang_disposeString(availability->Message);
6122}
6123
6124CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6125 if (clang_isDeclaration(cursor.kind))
6126 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6127
6128 return CXLanguage_Invalid;
6129}
6130
6131 /// \brief If the given cursor is the "templated" declaration
6132 /// descibing a class or function template, return the class or
6133 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006134static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006135 if (!D)
6136 return 0;
6137
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006138 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006139 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6140 return FunTmpl;
6141
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006142 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006143 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6144 return ClassTmpl;
6145
6146 return D;
6147}
6148
6149CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6150 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006151 if (const Decl *D = getCursorDecl(cursor)) {
6152 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006153 if (!DC)
6154 return clang_getNullCursor();
6155
6156 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6157 getCursorTU(cursor));
6158 }
6159 }
6160
6161 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006162 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006163 return MakeCXCursor(D, getCursorTU(cursor));
6164 }
6165
6166 return clang_getNullCursor();
6167}
6168
6169CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6170 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006171 if (const Decl *D = getCursorDecl(cursor)) {
6172 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006173 if (!DC)
6174 return clang_getNullCursor();
6175
6176 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6177 getCursorTU(cursor));
6178 }
6179 }
6180
6181 // FIXME: Note that we can't easily compute the lexical context of a
6182 // statement or expression, so we return nothing.
6183 return clang_getNullCursor();
6184}
6185
6186CXFile clang_getIncludedFile(CXCursor cursor) {
6187 if (cursor.kind != CXCursor_InclusionDirective)
6188 return 0;
6189
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006190 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006191 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006192}
6193
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006194unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6195 if (C.kind != CXCursor_ObjCPropertyDecl)
6196 return CXObjCPropertyAttr_noattr;
6197
6198 unsigned Result = CXObjCPropertyAttr_noattr;
6199 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6200 ObjCPropertyDecl::PropertyAttributeKind Attr =
6201 PD->getPropertyAttributesAsWritten();
6202
6203#define SET_CXOBJCPROP_ATTR(A) \
6204 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6205 Result |= CXObjCPropertyAttr_##A
6206 SET_CXOBJCPROP_ATTR(readonly);
6207 SET_CXOBJCPROP_ATTR(getter);
6208 SET_CXOBJCPROP_ATTR(assign);
6209 SET_CXOBJCPROP_ATTR(readwrite);
6210 SET_CXOBJCPROP_ATTR(retain);
6211 SET_CXOBJCPROP_ATTR(copy);
6212 SET_CXOBJCPROP_ATTR(nonatomic);
6213 SET_CXOBJCPROP_ATTR(setter);
6214 SET_CXOBJCPROP_ATTR(atomic);
6215 SET_CXOBJCPROP_ATTR(weak);
6216 SET_CXOBJCPROP_ATTR(strong);
6217 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6218#undef SET_CXOBJCPROP_ATTR
6219
6220 return Result;
6221}
6222
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006223unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6224 if (!clang_isDeclaration(C.kind))
6225 return CXObjCDeclQualifier_None;
6226
6227 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6228 const Decl *D = getCursorDecl(C);
6229 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6230 QT = MD->getObjCDeclQualifier();
6231 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6232 QT = PD->getObjCDeclQualifier();
6233 if (QT == Decl::OBJC_TQ_None)
6234 return CXObjCDeclQualifier_None;
6235
6236 unsigned Result = CXObjCDeclQualifier_None;
6237 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6238 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6239 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6240 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6241 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6242 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6243
6244 return Result;
6245}
6246
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006247unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6248 if (!clang_isDeclaration(C.kind))
6249 return 0;
6250
6251 const Decl *D = getCursorDecl(C);
6252 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6253 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6254 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6255 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6256
6257 return 0;
6258}
6259
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006260unsigned clang_Cursor_isVariadic(CXCursor C) {
6261 if (!clang_isDeclaration(C.kind))
6262 return 0;
6263
6264 const Decl *D = getCursorDecl(C);
6265 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6266 return FD->isVariadic();
6267 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6268 return MD->isVariadic();
6269
6270 return 0;
6271}
6272
Guy Benyei11169dd2012-12-18 14:30:41 +00006273CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6274 if (!clang_isDeclaration(C.kind))
6275 return clang_getNullRange();
6276
6277 const Decl *D = getCursorDecl(C);
6278 ASTContext &Context = getCursorContext(C);
6279 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6280 if (!RC)
6281 return clang_getNullRange();
6282
6283 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6284}
6285
6286CXString clang_Cursor_getRawCommentText(CXCursor C) {
6287 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006288 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006289
6290 const Decl *D = getCursorDecl(C);
6291 ASTContext &Context = getCursorContext(C);
6292 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6293 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6294 StringRef();
6295
6296 // Don't duplicate the string because RawText points directly into source
6297 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006298 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006299}
6300
6301CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6302 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006303 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006304
6305 const Decl *D = getCursorDecl(C);
6306 const ASTContext &Context = getCursorContext(C);
6307 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6308
6309 if (RC) {
6310 StringRef BriefText = RC->getBriefText(Context);
6311
6312 // Don't duplicate the string because RawComment ensures that this memory
6313 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006314 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006315 }
6316
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006317 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006318}
6319
6320CXComment clang_Cursor_getParsedComment(CXCursor C) {
6321 if (!clang_isDeclaration(C.kind))
6322 return cxcomment::createCXComment(NULL, NULL);
6323
6324 const Decl *D = getCursorDecl(C);
6325 const ASTContext &Context = getCursorContext(C);
6326 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6327
6328 return cxcomment::createCXComment(FC, getCursorTU(C));
6329}
6330
6331CXModule clang_Cursor_getModule(CXCursor C) {
6332 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006333 if (const ImportDecl *ImportD =
6334 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006335 return ImportD->getImportedModule();
6336 }
6337
6338 return 0;
6339}
6340
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006341CXFile clang_Module_getASTFile(CXModule CXMod) {
6342 if (!CXMod)
6343 return 0;
6344 Module *Mod = static_cast<Module*>(CXMod);
6345 return const_cast<FileEntry *>(Mod->getASTFile());
6346}
6347
Guy Benyei11169dd2012-12-18 14:30:41 +00006348CXModule clang_Module_getParent(CXModule CXMod) {
6349 if (!CXMod)
6350 return 0;
6351 Module *Mod = static_cast<Module*>(CXMod);
6352 return Mod->Parent;
6353}
6354
6355CXString clang_Module_getName(CXModule CXMod) {
6356 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006357 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006358 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006359 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006360}
6361
6362CXString clang_Module_getFullName(CXModule CXMod) {
6363 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006364 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006365 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006366 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006367}
6368
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006369unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6370 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006371 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006372 LOG_BAD_TU(TU);
6373 return 0;
6374 }
6375 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006376 return 0;
6377 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006378 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6379 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6380 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006381}
6382
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006383CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6384 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006385 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006386 LOG_BAD_TU(TU);
6387 return 0;
6388 }
6389 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006390 return 0;
6391 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006392 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006393
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006394 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6395 if (Index < TopHeaders.size())
6396 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006397
6398 return 0;
6399}
6400
6401} // end: extern "C"
6402
6403//===----------------------------------------------------------------------===//
6404// C++ AST instrospection.
6405//===----------------------------------------------------------------------===//
6406
6407extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006408unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6409 if (!clang_isDeclaration(C.kind))
6410 return 0;
6411
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006412 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006413 const CXXMethodDecl *Method =
6414 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006415 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6416}
6417
Guy Benyei11169dd2012-12-18 14:30:41 +00006418unsigned clang_CXXMethod_isStatic(CXCursor C) {
6419 if (!clang_isDeclaration(C.kind))
6420 return 0;
6421
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006422 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006423 const CXXMethodDecl *Method =
6424 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006425 return (Method && Method->isStatic()) ? 1 : 0;
6426}
6427
6428unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6429 if (!clang_isDeclaration(C.kind))
6430 return 0;
6431
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006432 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006433 const CXXMethodDecl *Method =
6434 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006435 return (Method && Method->isVirtual()) ? 1 : 0;
6436}
6437} // end: extern "C"
6438
6439//===----------------------------------------------------------------------===//
6440// Attribute introspection.
6441//===----------------------------------------------------------------------===//
6442
6443extern "C" {
6444CXType clang_getIBOutletCollectionType(CXCursor C) {
6445 if (C.kind != CXCursor_IBOutletCollectionAttr)
6446 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6447
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006448 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006449 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6450
6451 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6452}
6453} // end: extern "C"
6454
6455//===----------------------------------------------------------------------===//
6456// Inspecting memory usage.
6457//===----------------------------------------------------------------------===//
6458
6459typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6460
6461static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6462 enum CXTUResourceUsageKind k,
6463 unsigned long amount) {
6464 CXTUResourceUsageEntry entry = { k, amount };
6465 entries.push_back(entry);
6466}
6467
6468extern "C" {
6469
6470const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6471 const char *str = "";
6472 switch (kind) {
6473 case CXTUResourceUsage_AST:
6474 str = "ASTContext: expressions, declarations, and types";
6475 break;
6476 case CXTUResourceUsage_Identifiers:
6477 str = "ASTContext: identifiers";
6478 break;
6479 case CXTUResourceUsage_Selectors:
6480 str = "ASTContext: selectors";
6481 break;
6482 case CXTUResourceUsage_GlobalCompletionResults:
6483 str = "Code completion: cached global results";
6484 break;
6485 case CXTUResourceUsage_SourceManagerContentCache:
6486 str = "SourceManager: content cache allocator";
6487 break;
6488 case CXTUResourceUsage_AST_SideTables:
6489 str = "ASTContext: side tables";
6490 break;
6491 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6492 str = "SourceManager: malloc'ed memory buffers";
6493 break;
6494 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6495 str = "SourceManager: mmap'ed memory buffers";
6496 break;
6497 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6498 str = "ExternalASTSource: malloc'ed memory buffers";
6499 break;
6500 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6501 str = "ExternalASTSource: mmap'ed memory buffers";
6502 break;
6503 case CXTUResourceUsage_Preprocessor:
6504 str = "Preprocessor: malloc'ed memory";
6505 break;
6506 case CXTUResourceUsage_PreprocessingRecord:
6507 str = "Preprocessor: PreprocessingRecord";
6508 break;
6509 case CXTUResourceUsage_SourceManager_DataStructures:
6510 str = "SourceManager: data structures and tables";
6511 break;
6512 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6513 str = "Preprocessor: header search tables";
6514 break;
6515 }
6516 return str;
6517}
6518
6519CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006520 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006521 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006522 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6523 return usage;
6524 }
6525
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006526 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006527 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6528 ASTContext &astContext = astUnit->getASTContext();
6529
6530 // How much memory is used by AST nodes and types?
6531 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6532 (unsigned long) astContext.getASTAllocatedMemory());
6533
6534 // How much memory is used by identifiers?
6535 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6536 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6537
6538 // How much memory is used for selectors?
6539 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6540 (unsigned long) astContext.Selectors.getTotalMemory());
6541
6542 // How much memory is used by ASTContext's side tables?
6543 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6544 (unsigned long) astContext.getSideTableAllocatedMemory());
6545
6546 // How much memory is used for caching global code completion results?
6547 unsigned long completionBytes = 0;
6548 if (GlobalCodeCompletionAllocator *completionAllocator =
6549 astUnit->getCachedCompletionAllocator().getPtr()) {
6550 completionBytes = completionAllocator->getTotalMemory();
6551 }
6552 createCXTUResourceUsageEntry(*entries,
6553 CXTUResourceUsage_GlobalCompletionResults,
6554 completionBytes);
6555
6556 // How much memory is being used by SourceManager's content cache?
6557 createCXTUResourceUsageEntry(*entries,
6558 CXTUResourceUsage_SourceManagerContentCache,
6559 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6560
6561 // How much memory is being used by the MemoryBuffer's in SourceManager?
6562 const SourceManager::MemoryBufferSizes &srcBufs =
6563 astUnit->getSourceManager().getMemoryBufferSizes();
6564
6565 createCXTUResourceUsageEntry(*entries,
6566 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6567 (unsigned long) srcBufs.malloc_bytes);
6568 createCXTUResourceUsageEntry(*entries,
6569 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6570 (unsigned long) srcBufs.mmap_bytes);
6571 createCXTUResourceUsageEntry(*entries,
6572 CXTUResourceUsage_SourceManager_DataStructures,
6573 (unsigned long) astContext.getSourceManager()
6574 .getDataStructureSizes());
6575
6576 // How much memory is being used by the ExternalASTSource?
6577 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6578 const ExternalASTSource::MemoryBufferSizes &sizes =
6579 esrc->getMemoryBufferSizes();
6580
6581 createCXTUResourceUsageEntry(*entries,
6582 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6583 (unsigned long) sizes.malloc_bytes);
6584 createCXTUResourceUsageEntry(*entries,
6585 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6586 (unsigned long) sizes.mmap_bytes);
6587 }
6588
6589 // How much memory is being used by the Preprocessor?
6590 Preprocessor &pp = astUnit->getPreprocessor();
6591 createCXTUResourceUsageEntry(*entries,
6592 CXTUResourceUsage_Preprocessor,
6593 pp.getTotalMemory());
6594
6595 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6596 createCXTUResourceUsageEntry(*entries,
6597 CXTUResourceUsage_PreprocessingRecord,
6598 pRec->getTotalMemory());
6599 }
6600
6601 createCXTUResourceUsageEntry(*entries,
6602 CXTUResourceUsage_Preprocessor_HeaderSearch,
6603 pp.getHeaderSearchInfo().getTotalMemory());
6604
6605 CXTUResourceUsage usage = { (void*) entries.get(),
6606 (unsigned) entries->size(),
6607 entries->size() ? &(*entries)[0] : 0 };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006608 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006609 return usage;
6610}
6611
6612void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6613 if (usage.data)
6614 delete (MemUsageEntries*) usage.data;
6615}
6616
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006617CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6618 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006619 skipped->count = 0;
6620 skipped->ranges = 0;
6621
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006622 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006623 LOG_BAD_TU(TU);
6624 return skipped;
6625 }
6626
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006627 if (!file)
6628 return skipped;
6629
6630 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6631 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6632 if (!ppRec)
6633 return skipped;
6634
6635 ASTContext &Ctx = astUnit->getASTContext();
6636 SourceManager &sm = Ctx.getSourceManager();
6637 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6638 FileID wantedFileID = sm.translateFile(fileEntry);
6639
6640 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6641 std::vector<SourceRange> wantedRanges;
6642 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6643 i != ei; ++i) {
6644 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6645 wantedRanges.push_back(*i);
6646 }
6647
6648 skipped->count = wantedRanges.size();
6649 skipped->ranges = new CXSourceRange[skipped->count];
6650 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6651 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6652
6653 return skipped;
6654}
6655
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006656void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6657 if (ranges) {
6658 delete[] ranges->ranges;
6659 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006660 }
6661}
6662
Guy Benyei11169dd2012-12-18 14:30:41 +00006663} // end extern "C"
6664
6665void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6666 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6667 for (unsigned I = 0; I != Usage.numEntries; ++I)
6668 fprintf(stderr, " %s: %lu\n",
6669 clang_getTUResourceUsageName(Usage.entries[I].kind),
6670 Usage.entries[I].amount);
6671
6672 clang_disposeCXTUResourceUsage(Usage);
6673}
6674
6675//===----------------------------------------------------------------------===//
6676// Misc. utility functions.
6677//===----------------------------------------------------------------------===//
6678
6679/// Default to using an 8 MB stack size on "safety" threads.
6680static unsigned SafetyStackThreadSize = 8 << 20;
6681
6682namespace clang {
6683
6684bool RunSafely(llvm::CrashRecoveryContext &CRC,
6685 void (*Fn)(void*), void *UserData,
6686 unsigned Size) {
6687 if (!Size)
6688 Size = GetSafetyThreadStackSize();
6689 if (Size)
6690 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6691 return CRC.RunSafely(Fn, UserData);
6692}
6693
6694unsigned GetSafetyThreadStackSize() {
6695 return SafetyStackThreadSize;
6696}
6697
6698void SetSafetyThreadStackSize(unsigned Value) {
6699 SafetyStackThreadSize = Value;
6700}
6701
6702}
6703
6704void clang::setThreadBackgroundPriority() {
6705 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6706 return;
6707
6708 // FIXME: Move to llvm/Support and make it cross-platform.
6709#ifdef __APPLE__
6710 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6711#endif
6712}
6713
6714void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6715 if (!Unit)
6716 return;
6717
6718 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6719 DEnd = Unit->stored_diag_end();
6720 D != DEnd; ++D) {
6721 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6722 CXString Msg = clang_formatDiagnostic(&Diag,
6723 clang_defaultDiagnosticDisplayOptions());
6724 fprintf(stderr, "%s\n", clang_getCString(Msg));
6725 clang_disposeString(Msg);
6726 }
6727#ifdef LLVM_ON_WIN32
6728 // On Windows, force a flush, since there may be multiple copies of
6729 // stderr and stdout in the file system, all with different buffers
6730 // but writing to the same device.
6731 fflush(stderr);
6732#endif
6733}
6734
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006735MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6736 SourceLocation MacroDefLoc,
6737 CXTranslationUnit TU){
6738 if (MacroDefLoc.isInvalid() || !TU)
6739 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006740 if (!II.hadMacroDefinition())
6741 return 0;
6742
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006743 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006744 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006745 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006746 if (MD) {
6747 for (MacroDirective::DefInfo
6748 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6749 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6750 return Def.getMacroInfo();
6751 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006752 }
6753
6754 return 0;
6755}
6756
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006757const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6758 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006759 if (!MacroDef || !TU)
6760 return 0;
6761 const IdentifierInfo *II = MacroDef->getName();
6762 if (!II)
6763 return 0;
6764
6765 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6766}
6767
6768MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6769 const Token &Tok,
6770 CXTranslationUnit TU) {
6771 if (!MI || !TU)
6772 return 0;
6773 if (Tok.isNot(tok::raw_identifier))
6774 return 0;
6775
6776 if (MI->getNumTokens() == 0)
6777 return 0;
6778 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6779 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006780 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006781
6782 // Check that the token is inside the definition and not its argument list.
6783 SourceManager &SM = Unit->getSourceManager();
6784 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6785 return 0;
6786 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6787 return 0;
6788
6789 Preprocessor &PP = Unit->getPreprocessor();
6790 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6791 if (!PPRec)
6792 return 0;
6793
6794 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6795 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6796 if (!II.hadMacroDefinition())
6797 return 0;
6798
6799 // Check that the identifier is not one of the macro arguments.
6800 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6801 return 0;
6802
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006803 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6804 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006805 return 0;
6806
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006807 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006808}
6809
6810MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6811 SourceLocation Loc,
6812 CXTranslationUnit TU) {
6813 if (Loc.isInvalid() || !MI || !TU)
6814 return 0;
6815
6816 if (MI->getNumTokens() == 0)
6817 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006818 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006819 Preprocessor &PP = Unit->getPreprocessor();
6820 if (!PP.getPreprocessingRecord())
6821 return 0;
6822 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6823 Token Tok;
6824 if (PP.getRawToken(Loc, Tok))
6825 return 0;
6826
6827 return checkForMacroInMacroDefinition(MI, Tok, TU);
6828}
6829
Guy Benyei11169dd2012-12-18 14:30:41 +00006830extern "C" {
6831
6832CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006833 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006834}
6835
6836} // end: extern "C"
6837
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006838Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6839 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006840 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006841 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006842 if (Unit->isMainFileAST())
6843 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006844 return *this;
6845 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006846 } else {
6847 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006848 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006849 return *this;
6850}
6851
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006852Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6853 *this << FE->getName();
6854 return *this;
6855}
6856
6857Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6858 CXString cursorName = clang_getCursorDisplayName(cursor);
6859 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6860 clang_disposeString(cursorName);
6861 return *this;
6862}
6863
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006864Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6865 CXFile File;
6866 unsigned Line, Column;
6867 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6868 CXString FileName = clang_getFileName(File);
6869 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6870 clang_disposeString(FileName);
6871 return *this;
6872}
6873
6874Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6875 CXSourceLocation BLoc = clang_getRangeStart(range);
6876 CXSourceLocation ELoc = clang_getRangeEnd(range);
6877
6878 CXFile BFile;
6879 unsigned BLine, BColumn;
6880 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6881
6882 CXFile EFile;
6883 unsigned ELine, EColumn;
6884 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6885
6886 CXString BFileName = clang_getFileName(BFile);
6887 if (BFile == EFile) {
6888 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6889 BLine, BColumn, ELine, EColumn);
6890 } else {
6891 CXString EFileName = clang_getFileName(EFile);
6892 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6893 BLine, BColumn)
6894 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6895 ELine, EColumn);
6896 clang_disposeString(EFileName);
6897 }
6898 clang_disposeString(BFileName);
6899 return *this;
6900}
6901
6902Logger &cxindex::Logger::operator<<(CXString Str) {
6903 *this << clang_getCString(Str);
6904 return *this;
6905}
6906
6907Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6908 LogOS << Fmt;
6909 return *this;
6910}
6911
6912cxindex::Logger::~Logger() {
6913 LogOS.flush();
6914
6915 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6916
6917 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6918
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006919 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006920 OS << "[libclang:" << Name << ':';
6921
6922 // FIXME: Portability.
6923#if HAVE_PTHREAD_H && __APPLE__
6924 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6925 OS << tid << ':';
6926#endif
6927
6928 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6929 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6930 OS << Msg.str() << '\n';
6931
6932 if (Trace) {
6933 llvm::sys::PrintStackTrace(stderr);
6934 OS << "--------------------------------------------------\n";
6935 }
6936}