blob: 9d59fa7c7b5ba7edeeda7cf6ec9cb16ce8f1a386 [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXComment.h"
19#include "CXCursor.h"
20#include "CXSourceLocation.h"
21#include "CXString.h"
22#include "CXTranslationUnit.h"
23#include "CXType.h"
24#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000025#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000030#include "clang/Basic/Version.h"
31#include "clang/Frontend/ASTUnit.h"
32#include "clang/Frontend/CompilerInstance.h"
33#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000034#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000035#include "clang/Lex/HeaderSearch.h"
36#include "clang/Lex/Lexer.h"
37#include "clang/Lex/PreprocessingRecord.h"
38#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000039#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000040#include "llvm/ADT/Optional.h"
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/StringSwitch.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000043#include "llvm/Config/config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000044#include "llvm/Support/Compiler.h"
45#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000046#include "llvm/Support/Format.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/MemoryBuffer.h"
48#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000049#include "llvm/Support/Program.h"
50#include "llvm/Support/SaveAndRestore.h"
51#include "llvm/Support/Signals.h"
52#include "llvm/Support/Threading.h"
53#include "llvm/Support/Timer.h"
54#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000055
56#if HAVE_PTHREAD_H
57#include <pthread.h>
58#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000059
60using namespace clang;
61using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000062using namespace clang::cxtu;
63using namespace clang::cxindex;
64
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000065CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
66 if (!AU)
Guy Benyei11169dd2012-12-18 14:30:41 +000067 return 0;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000068 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000069 CXTranslationUnit D = new CXTranslationUnitImpl();
70 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000071 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000072 D->StringPool = new cxstring::CXStringPool();
Guy Benyei11169dd2012-12-18 14:30:41 +000073 D->Diagnostics = 0;
74 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Dmitri Gribenko9e605112013-11-13 22:16:51 +000075 D->CommentToXML = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +000076 return D;
77}
78
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000079bool cxtu::isASTReadError(ASTUnit *AU) {
80 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
81 DEnd = AU->stored_diag_end();
82 D != DEnd; ++D) {
83 if (D->getLevel() >= DiagnosticsEngine::Error &&
84 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
85 diag::DiagCat_AST_Deserialization_Issue)
86 return true;
87 }
88 return false;
89}
90
Guy Benyei11169dd2012-12-18 14:30:41 +000091cxtu::CXTUOwner::~CXTUOwner() {
92 if (TU)
93 clang_disposeTranslationUnit(TU);
94}
95
96/// \brief Compare two source ranges to determine their relative position in
97/// the translation unit.
98static RangeComparisonResult RangeCompare(SourceManager &SM,
99 SourceRange R1,
100 SourceRange R2) {
101 assert(R1.isValid() && "First range is invalid?");
102 assert(R2.isValid() && "Second range is invalid?");
103 if (R1.getEnd() != R2.getBegin() &&
104 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
105 return RangeBefore;
106 if (R2.getEnd() != R1.getBegin() &&
107 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
108 return RangeAfter;
109 return RangeOverlap;
110}
111
112/// \brief Determine if a source location falls within, before, or after a
113/// a given source range.
114static RangeComparisonResult LocationCompare(SourceManager &SM,
115 SourceLocation L, SourceRange R) {
116 assert(R.isValid() && "First range is invalid?");
117 assert(L.isValid() && "Second range is invalid?");
118 if (L == R.getBegin() || L == R.getEnd())
119 return RangeOverlap;
120 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
121 return RangeBefore;
122 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
123 return RangeAfter;
124 return RangeOverlap;
125}
126
127/// \brief Translate a Clang source range into a CIndex source range.
128///
129/// Clang internally represents ranges where the end location points to the
130/// start of the token at the end. However, for external clients it is more
131/// useful to have a CXSourceRange be a proper half-open interval. This routine
132/// does the appropriate translation.
133CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
134 const LangOptions &LangOpts,
135 const CharSourceRange &R) {
136 // We want the last character in this location, so we will adjust the
137 // location accordingly.
138 SourceLocation EndLoc = R.getEnd();
139 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
140 EndLoc = SM.getExpansionRange(EndLoc).second;
141 if (R.isTokenRange() && !EndLoc.isInvalid()) {
142 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
143 SM, LangOpts);
144 EndLoc = EndLoc.getLocWithOffset(Length);
145 }
146
Bill Wendlingeade3622013-01-23 08:25:41 +0000147 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000148 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000149 R.getBegin().getRawEncoding(),
150 EndLoc.getRawEncoding()
151 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000152 return Result;
153}
154
155//===----------------------------------------------------------------------===//
156// Cursor visitor.
157//===----------------------------------------------------------------------===//
158
159static SourceRange getRawCursorExtent(CXCursor C);
160static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
161
162
163RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
164 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
165}
166
167/// \brief Visit the given cursor and, if requested by the visitor,
168/// its children.
169///
170/// \param Cursor the cursor to visit.
171///
172/// \param CheckedRegionOfInterest if true, then the caller already checked
173/// that this cursor is within the region of interest.
174///
175/// \returns true if the visitation should be aborted, false if it
176/// should continue.
177bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
178 if (clang_isInvalid(Cursor.kind))
179 return false;
180
181 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000182 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000183 if (!D) {
184 assert(0 && "Invalid declaration cursor");
185 return true; // abort.
186 }
187
188 // Ignore implicit declarations, unless it's an objc method because
189 // currently we should report implicit methods for properties when indexing.
190 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
191 return false;
192 }
193
194 // If we have a range of interest, and this cursor doesn't intersect with it,
195 // we're done.
196 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
197 SourceRange Range = getRawCursorExtent(Cursor);
198 if (Range.isInvalid() || CompareRegionOfInterest(Range))
199 return false;
200 }
201
202 switch (Visitor(Cursor, Parent, ClientData)) {
203 case CXChildVisit_Break:
204 return true;
205
206 case CXChildVisit_Continue:
207 return false;
208
209 case CXChildVisit_Recurse: {
210 bool ret = VisitChildren(Cursor);
211 if (PostChildrenVisitor)
212 if (PostChildrenVisitor(Cursor, ClientData))
213 return true;
214 return ret;
215 }
216 }
217
218 llvm_unreachable("Invalid CXChildVisitResult!");
219}
220
221static bool visitPreprocessedEntitiesInRange(SourceRange R,
222 PreprocessingRecord &PPRec,
223 CursorVisitor &Visitor) {
224 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
225 FileID FID;
226
227 if (!Visitor.shouldVisitIncludedEntities()) {
228 // If the begin/end of the range lie in the same FileID, do the optimization
229 // where we skip preprocessed entities that do not come from the same FileID.
230 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
231 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
232 FID = FileID();
233 }
234
235 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
236 Entities = PPRec.getPreprocessedEntitiesInRange(R);
237 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
238 PPRec, FID);
239}
240
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000241bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000242 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000243 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000244
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000245 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 SourceManager &SM = Unit->getSourceManager();
247
248 std::pair<FileID, unsigned>
249 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
250 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
251
252 if (End.first != Begin.first) {
253 // If the end does not reside in the same file, try to recover by
254 // picking the end of the file of begin location.
255 End.first = Begin.first;
256 End.second = SM.getFileIDSize(Begin.first);
257 }
258
259 assert(Begin.first == End.first);
260 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000261 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000262
263 FileID File = Begin.first;
264 unsigned Offset = Begin.second;
265 unsigned Length = End.second - Begin.second;
266
267 if (!VisitDeclsOnly && !VisitPreprocessorLast)
268 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000271 if (visitDeclsFromFileRegion(File, Offset, Length))
272 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000273
274 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000275 return visitPreprocessedEntitiesInRegion();
276
277 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000278}
279
280static bool isInLexicalContext(Decl *D, DeclContext *DC) {
281 if (!DC)
282 return false;
283
284 for (DeclContext *DeclDC = D->getLexicalDeclContext();
285 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
286 if (DeclDC == DC)
287 return true;
288 }
289 return false;
290}
291
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000292bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000293 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000294 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000295 SourceManager &SM = Unit->getSourceManager();
296 SourceRange Range = RegionOfInterest;
297
298 SmallVector<Decl *, 16> Decls;
299 Unit->findFileRegionDecls(File, Offset, Length, Decls);
300
301 // If we didn't find any file level decls for the file, try looking at the
302 // file that it was included from.
303 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
304 bool Invalid = false;
305 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
306 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000307 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000308
309 SourceLocation Outer;
310 if (SLEntry.isFile())
311 Outer = SLEntry.getFile().getIncludeLoc();
312 else
313 Outer = SLEntry.getExpansion().getExpansionLocStart();
314 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000317 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000318 Length = 0;
319 Unit->findFileRegionDecls(File, Offset, Length, Decls);
320 }
321
322 assert(!Decls.empty());
323
324 bool VisitedAtLeastOnce = false;
325 DeclContext *CurDC = 0;
Craig Topper2341c0d2013-07-04 03:08:24 +0000326 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
327 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000328 Decl *D = *DIt;
329 if (D->getSourceRange().isInvalid())
330 continue;
331
332 if (isInLexicalContext(D, CurDC))
333 continue;
334
335 CurDC = dyn_cast<DeclContext>(D);
336
337 if (TagDecl *TD = dyn_cast<TagDecl>(D))
338 if (!TD->isFreeStanding())
339 continue;
340
341 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
342 if (CompRes == RangeBefore)
343 continue;
344 if (CompRes == RangeAfter)
345 break;
346
347 assert(CompRes == RangeOverlap);
348 VisitedAtLeastOnce = true;
349
350 if (isa<ObjCContainerDecl>(D)) {
351 FileDI_current = &DIt;
352 FileDE_current = DE;
353 } else {
354 FileDI_current = 0;
355 }
356
357 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000358 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000359 }
360
361 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000362 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363
364 // No Decls overlapped with the range. Move up the lexical context until there
365 // is a context that contains the range or we reach the translation unit
366 // level.
367 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
368 : (*(DIt-1))->getLexicalDeclContext();
369
370 while (DC && !DC->isTranslationUnit()) {
371 Decl *D = cast<Decl>(DC);
372 SourceRange CurDeclRange = D->getSourceRange();
373 if (CurDeclRange.isInvalid())
374 break;
375
376 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000377 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
378 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000379 }
380
381 DC = D->getLexicalDeclContext();
382 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000383
384 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000385}
386
387bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
388 if (!AU->getPreprocessor().getPreprocessingRecord())
389 return false;
390
391 PreprocessingRecord &PPRec
392 = *AU->getPreprocessor().getPreprocessingRecord();
393 SourceManager &SM = AU->getSourceManager();
394
395 if (RegionOfInterest.isValid()) {
396 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
397 SourceLocation B = MappedRange.getBegin();
398 SourceLocation E = MappedRange.getEnd();
399
400 if (AU->isInPreambleFileID(B)) {
401 if (SM.isLoadedSourceLocation(E))
402 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
403 PPRec, *this);
404
405 // Beginning of range lies in the preamble but it also extends beyond
406 // it into the main file. Split the range into 2 parts, one covering
407 // the preamble and another covering the main file. This allows subsequent
408 // calls to visitPreprocessedEntitiesInRange to accept a source range that
409 // lies in the same FileID, allowing it to skip preprocessed entities that
410 // do not come from the same FileID.
411 bool breaked =
412 visitPreprocessedEntitiesInRange(
413 SourceRange(B, AU->getEndOfPreambleFileID()),
414 PPRec, *this);
415 if (breaked) return true;
416 return visitPreprocessedEntitiesInRange(
417 SourceRange(AU->getStartOfMainFileID(), E),
418 PPRec, *this);
419 }
420
421 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
422 }
423
424 bool OnlyLocalDecls
425 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
426
427 if (OnlyLocalDecls)
428 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
429 PPRec);
430
431 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
432}
433
434template<typename InputIterator>
435bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
436 InputIterator Last,
437 PreprocessingRecord &PPRec,
438 FileID FID) {
439 for (; First != Last; ++First) {
440 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
441 continue;
442
443 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000444 if (!PPE)
445 continue;
446
Guy Benyei11169dd2012-12-18 14:30:41 +0000447 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
448 if (Visit(MakeMacroExpansionCursor(ME, TU)))
449 return true;
450
451 continue;
452 }
453
454 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
455 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
456 return true;
457
458 continue;
459 }
460
461 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
462 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
463 return true;
464
465 continue;
466 }
467 }
468
469 return false;
470}
471
472/// \brief Visit the children of the given cursor.
473///
474/// \returns true if the visitation should be aborted, false if it
475/// should continue.
476bool CursorVisitor::VisitChildren(CXCursor Cursor) {
477 if (clang_isReference(Cursor.kind) &&
478 Cursor.kind != CXCursor_CXXBaseSpecifier) {
479 // By definition, references have no children.
480 return false;
481 }
482
483 // Set the Parent field to Cursor, then back to its old value once we're
484 // done.
485 SetParentRAII SetParent(Parent, StmtParent, Cursor);
486
487 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000488 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000489 if (!D)
490 return false;
491
492 return VisitAttributes(D) || Visit(D);
493 }
494
495 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000496 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 return Visit(S);
498
499 return false;
500 }
501
502 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000503 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000504 return Visit(E);
505
506 return false;
507 }
508
509 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000510 CXTranslationUnit TU = getCursorTU(Cursor);
511 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000512
513 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
514 for (unsigned I = 0; I != 2; ++I) {
515 if (VisitOrder[I]) {
516 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
517 RegionOfInterest.isInvalid()) {
518 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
519 TLEnd = CXXUnit->top_level_end();
520 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000521 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000522 return true;
523 }
524 } else if (VisitDeclContext(
525 CXXUnit->getASTContext().getTranslationUnitDecl()))
526 return true;
527 continue;
528 }
529
530 // Walk the preprocessing record.
531 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
532 visitPreprocessedEntitiesInRegion();
533 }
534
535 return false;
536 }
537
538 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000539 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000540 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
541 return Visit(BaseTSInfo->getTypeLoc());
542 }
543 }
544 }
545
546 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000547 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000549 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000550 return Visit(cxcursor::MakeCursorObjCClassRef(
551 ObjT->getInterface(),
552 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000553 }
554
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000555 // If pointing inside a macro definition, check if the token is an identifier
556 // that was ever defined as a macro. In such a case, create a "pseudo" macro
557 // expansion cursor for that token.
558 SourceLocation BeginLoc = RegionOfInterest.getBegin();
559 if (Cursor.kind == CXCursor_MacroDefinition &&
560 BeginLoc == RegionOfInterest.getEnd()) {
561 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000562 const MacroInfo *MI =
563 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000564 if (MacroDefinition *MacroDef =
565 checkForMacroInMacroDefinition(MI, Loc, TU))
566 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
567 }
568
Guy Benyei11169dd2012-12-18 14:30:41 +0000569 // Nothing to visit at the moment.
570 return false;
571}
572
573bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
574 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
575 if (Visit(TSInfo->getTypeLoc()))
576 return true;
577
578 if (Stmt *Body = B->getBody())
579 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
580
581 return false;
582}
583
Ted Kremenek03325582013-02-21 01:29:01 +0000584Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000585 if (RegionOfInterest.isValid()) {
586 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
587 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000588 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000589
590 switch (CompareRegionOfInterest(Range)) {
591 case RangeBefore:
592 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000593 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000594
595 case RangeAfter:
596 // This declaration comes after the region of interest; we're done.
597 return false;
598
599 case RangeOverlap:
600 // This declaration overlaps the region of interest; visit it.
601 break;
602 }
603 }
604 return true;
605}
606
607bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
608 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
609
610 // FIXME: Eventually remove. This part of a hack to support proper
611 // iteration over all Decls contained lexically within an ObjC container.
612 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
613 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
614
615 for ( ; I != E; ++I) {
616 Decl *D = *I;
617 if (D->getLexicalDeclContext() != DC)
618 continue;
619 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
620
621 // Ignore synthesized ivars here, otherwise if we have something like:
622 // @synthesize prop = _prop;
623 // and '_prop' is not declared, we will encounter a '_prop' ivar before
624 // encountering the 'prop' synthesize declaration and we will think that
625 // we passed the region-of-interest.
626 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
627 if (ivarD->getSynthesize())
628 continue;
629 }
630
631 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
632 // declarations is a mismatch with the compiler semantics.
633 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
634 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
635 if (!ID->isThisDeclarationADefinition())
636 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
637
638 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
639 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
640 if (!PD->isThisDeclarationADefinition())
641 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
642 }
643
Ted Kremenek03325582013-02-21 01:29:01 +0000644 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000645 if (!V.hasValue())
646 continue;
647 if (!V.getValue())
648 return false;
649 if (Visit(Cursor, true))
650 return true;
651 }
652 return false;
653}
654
655bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
656 llvm_unreachable("Translation units are visited directly by Visit()");
657}
658
659bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
660 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
661 return Visit(TSInfo->getTypeLoc());
662
663 return false;
664}
665
666bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
667 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
668 return Visit(TSInfo->getTypeLoc());
669
670 return false;
671}
672
673bool CursorVisitor::VisitTagDecl(TagDecl *D) {
674 return VisitDeclContext(D);
675}
676
677bool CursorVisitor::VisitClassTemplateSpecializationDecl(
678 ClassTemplateSpecializationDecl *D) {
679 bool ShouldVisitBody = false;
680 switch (D->getSpecializationKind()) {
681 case TSK_Undeclared:
682 case TSK_ImplicitInstantiation:
683 // Nothing to visit
684 return false;
685
686 case TSK_ExplicitInstantiationDeclaration:
687 case TSK_ExplicitInstantiationDefinition:
688 break;
689
690 case TSK_ExplicitSpecialization:
691 ShouldVisitBody = true;
692 break;
693 }
694
695 // Visit the template arguments used in the specialization.
696 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
697 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000698 if (TemplateSpecializationTypeLoc TSTLoc =
699 TL.getAs<TemplateSpecializationTypeLoc>()) {
700 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
701 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000702 return true;
703 }
704 }
705
706 if (ShouldVisitBody && VisitCXXRecordDecl(D))
707 return true;
708
709 return false;
710}
711
712bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
713 ClassTemplatePartialSpecializationDecl *D) {
714 // FIXME: Visit the "outer" template parameter lists on the TagDecl
715 // before visiting these template parameters.
716 if (VisitTemplateParameters(D->getTemplateParameters()))
717 return true;
718
719 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000720 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
721 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
722 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000723 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
724 return true;
725
726 return VisitCXXRecordDecl(D);
727}
728
729bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
730 // Visit the default argument.
731 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
732 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
733 if (Visit(DefArg->getTypeLoc()))
734 return true;
735
736 return false;
737}
738
739bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
740 if (Expr *Init = D->getInitExpr())
741 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
742 return false;
743}
744
745bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000746 unsigned NumParamList = DD->getNumTemplateParameterLists();
747 for (unsigned i = 0; i < NumParamList; i++) {
748 TemplateParameterList* Params = DD->getTemplateParameterList(i);
749 if (VisitTemplateParameters(Params))
750 return true;
751 }
752
Guy Benyei11169dd2012-12-18 14:30:41 +0000753 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
754 if (Visit(TSInfo->getTypeLoc()))
755 return true;
756
757 // Visit the nested-name-specifier, if present.
758 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
759 if (VisitNestedNameSpecifierLoc(QualifierLoc))
760 return true;
761
762 return false;
763}
764
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000765/// \brief Compare two base or member initializers based on their source order.
766static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
767 CXXCtorInitializer *const *Y) {
768 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
769}
770
Guy Benyei11169dd2012-12-18 14:30:41 +0000771bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000772 unsigned NumParamList = ND->getNumTemplateParameterLists();
773 for (unsigned i = 0; i < NumParamList; i++) {
774 TemplateParameterList* Params = ND->getTemplateParameterList(i);
775 if (VisitTemplateParameters(Params))
776 return true;
777 }
778
Guy Benyei11169dd2012-12-18 14:30:41 +0000779 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
780 // Visit the function declaration's syntactic components in the order
781 // written. This requires a bit of work.
782 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000783 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000784
785 // If we have a function declared directly (without the use of a typedef),
786 // visit just the return type. Otherwise, just visit the function's type
787 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000788 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000789 (!FTL && Visit(TL)))
790 return true;
791
792 // Visit the nested-name-specifier, if present.
793 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
794 if (VisitNestedNameSpecifierLoc(QualifierLoc))
795 return true;
796
797 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000798 if (!isa<CXXDestructorDecl>(ND))
799 if (VisitDeclarationNameInfo(ND->getNameInfo()))
800 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000801
802 // FIXME: Visit explicitly-specified template arguments!
803
804 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000805 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000806 return true;
807
Bill Wendling44426052012-12-20 19:22:21 +0000808 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000809 }
810
811 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
812 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
813 // Find the initializers that were written in the source.
814 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000815 for (auto *I : Constructor->inits()) {
816 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000817 continue;
818
Aaron Ballman0ad78302014-03-13 17:34:31 +0000819 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000820 }
821
822 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000823 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
824 &CompareCXXCtorInitializers);
825
Guy Benyei11169dd2012-12-18 14:30:41 +0000826 // Visit the initializers in source order
827 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
828 CXXCtorInitializer *Init = WrittenInits[I];
829 if (Init->isAnyMemberInitializer()) {
830 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
831 Init->getMemberLocation(), TU)))
832 return true;
833 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
834 if (Visit(TInfo->getTypeLoc()))
835 return true;
836 }
837
838 // Visit the initializer value.
839 if (Expr *Initializer = Init->getInit())
840 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
841 return true;
842 }
843 }
844
845 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
846 return true;
847 }
848
849 return false;
850}
851
852bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
853 if (VisitDeclaratorDecl(D))
854 return true;
855
856 if (Expr *BitWidth = D->getBitWidth())
857 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
858
859 return false;
860}
861
862bool CursorVisitor::VisitVarDecl(VarDecl *D) {
863 if (VisitDeclaratorDecl(D))
864 return true;
865
866 if (Expr *Init = D->getInit())
867 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
868
869 return false;
870}
871
872bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
873 if (VisitDeclaratorDecl(D))
874 return true;
875
876 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
877 if (Expr *DefArg = D->getDefaultArgument())
878 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
879
880 return false;
881}
882
883bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
884 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
885 // before visiting these template parameters.
886 if (VisitTemplateParameters(D->getTemplateParameters()))
887 return true;
888
889 return VisitFunctionDecl(D->getTemplatedDecl());
890}
891
892bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
893 // FIXME: Visit the "outer" template parameter lists on the TagDecl
894 // before visiting these template parameters.
895 if (VisitTemplateParameters(D->getTemplateParameters()))
896 return true;
897
898 return VisitCXXRecordDecl(D->getTemplatedDecl());
899}
900
901bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
902 if (VisitTemplateParameters(D->getTemplateParameters()))
903 return true;
904
905 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
906 VisitTemplateArgumentLoc(D->getDefaultArgument()))
907 return true;
908
909 return false;
910}
911
912bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000913 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000914 if (Visit(TSInfo->getTypeLoc()))
915 return true;
916
Aaron Ballman43b68be2014-03-07 17:50:17 +0000917 for (const auto *P : ND->params()) {
918 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000919 return true;
920 }
921
922 if (ND->isThisDeclarationADefinition() &&
923 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
924 return true;
925
926 return false;
927}
928
929template <typename DeclIt>
930static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
931 SourceManager &SM, SourceLocation EndLoc,
932 SmallVectorImpl<Decl *> &Decls) {
933 DeclIt next = *DI_current;
934 while (++next != DE_current) {
935 Decl *D_next = *next;
936 if (!D_next)
937 break;
938 SourceLocation L = D_next->getLocStart();
939 if (!L.isValid())
940 break;
941 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
942 *DI_current = next;
943 Decls.push_back(D_next);
944 continue;
945 }
946 break;
947 }
948}
949
Guy Benyei11169dd2012-12-18 14:30:41 +0000950bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
951 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
952 // an @implementation can lexically contain Decls that are not properly
953 // nested in the AST. When we identify such cases, we need to retrofit
954 // this nesting here.
955 if (!DI_current && !FileDI_current)
956 return VisitDeclContext(D);
957
958 // Scan the Decls that immediately come after the container
959 // in the current DeclContext. If any fall within the
960 // container's lexical region, stash them into a vector
961 // for later processing.
962 SmallVector<Decl *, 24> DeclsInContainer;
963 SourceLocation EndLoc = D->getSourceRange().getEnd();
964 SourceManager &SM = AU->getSourceManager();
965 if (EndLoc.isValid()) {
966 if (DI_current) {
967 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
968 DeclsInContainer);
969 } else {
970 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
971 DeclsInContainer);
972 }
973 }
974
975 // The common case.
976 if (DeclsInContainer.empty())
977 return VisitDeclContext(D);
978
979 // Get all the Decls in the DeclContext, and sort them with the
980 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000981 for (auto *SubDecl : D->decls()) {
982 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
983 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000984 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000985 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000986 }
987
988 // Now sort the Decls so that they appear in lexical order.
989 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000990 [&SM](Decl *A, Decl *B) {
991 SourceLocation L_A = A->getLocStart();
992 SourceLocation L_B = B->getLocStart();
993 assert(L_A.isValid() && L_B.isValid());
994 return SM.isBeforeInTranslationUnit(L_A, L_B);
995 });
Guy Benyei11169dd2012-12-18 14:30:41 +0000996
997 // Now visit the decls.
998 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
999 E = DeclsInContainer.end(); I != E; ++I) {
1000 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001001 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001002 if (!V.hasValue())
1003 continue;
1004 if (!V.getValue())
1005 return false;
1006 if (Visit(Cursor, true))
1007 return true;
1008 }
1009 return false;
1010}
1011
1012bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1013 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1014 TU)))
1015 return true;
1016
1017 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1018 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1019 E = ND->protocol_end(); I != E; ++I, ++PL)
1020 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1021 return true;
1022
1023 return VisitObjCContainerDecl(ND);
1024}
1025
1026bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1027 if (!PID->isThisDeclarationADefinition())
1028 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1029
1030 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1031 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1032 E = PID->protocol_end(); I != E; ++I, ++PL)
1033 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1034 return true;
1035
1036 return VisitObjCContainerDecl(PID);
1037}
1038
1039bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1040 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1041 return true;
1042
1043 // FIXME: This implements a workaround with @property declarations also being
1044 // installed in the DeclContext for the @interface. Eventually this code
1045 // should be removed.
1046 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1047 if (!CDecl || !CDecl->IsClassExtension())
1048 return false;
1049
1050 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1051 if (!ID)
1052 return false;
1053
1054 IdentifierInfo *PropertyId = PD->getIdentifier();
1055 ObjCPropertyDecl *prevDecl =
1056 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1057
1058 if (!prevDecl)
1059 return false;
1060
1061 // Visit synthesized methods since they will be skipped when visiting
1062 // the @interface.
1063 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1064 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1065 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1066 return true;
1067
1068 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1069 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1070 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1071 return true;
1072
1073 return false;
1074}
1075
1076bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1077 if (!D->isThisDeclarationADefinition()) {
1078 // Forward declaration is treated like a reference.
1079 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1080 }
1081
1082 // Issue callbacks for super class.
1083 if (D->getSuperClass() &&
1084 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1085 D->getSuperClassLoc(),
1086 TU)))
1087 return true;
1088
1089 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1090 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1091 E = D->protocol_end(); I != E; ++I, ++PL)
1092 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1093 return true;
1094
1095 return VisitObjCContainerDecl(D);
1096}
1097
1098bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1099 return VisitObjCContainerDecl(D);
1100}
1101
1102bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1103 // 'ID' could be null when dealing with invalid code.
1104 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1105 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1106 return true;
1107
1108 return VisitObjCImplDecl(D);
1109}
1110
1111bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1112#if 0
1113 // Issue callbacks for super class.
1114 // FIXME: No source location information!
1115 if (D->getSuperClass() &&
1116 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1117 D->getSuperClassLoc(),
1118 TU)))
1119 return true;
1120#endif
1121
1122 return VisitObjCImplDecl(D);
1123}
1124
1125bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1126 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1127 if (PD->isIvarNameSpecified())
1128 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1129
1130 return false;
1131}
1132
1133bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1134 return VisitDeclContext(D);
1135}
1136
1137bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1138 // Visit nested-name-specifier.
1139 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1140 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1141 return true;
1142
1143 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1144 D->getTargetNameLoc(), TU));
1145}
1146
1147bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1148 // Visit nested-name-specifier.
1149 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1150 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1151 return true;
1152 }
1153
1154 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1155 return true;
1156
1157 return VisitDeclarationNameInfo(D->getNameInfo());
1158}
1159
1160bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1161 // Visit nested-name-specifier.
1162 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1163 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1164 return true;
1165
1166 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1167 D->getIdentLocation(), TU));
1168}
1169
1170bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1171 // Visit nested-name-specifier.
1172 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1173 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1174 return true;
1175 }
1176
1177 return VisitDeclarationNameInfo(D->getNameInfo());
1178}
1179
1180bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1181 UnresolvedUsingTypenameDecl *D) {
1182 // Visit nested-name-specifier.
1183 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1184 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1185 return true;
1186
1187 return false;
1188}
1189
1190bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1191 switch (Name.getName().getNameKind()) {
1192 case clang::DeclarationName::Identifier:
1193 case clang::DeclarationName::CXXLiteralOperatorName:
1194 case clang::DeclarationName::CXXOperatorName:
1195 case clang::DeclarationName::CXXUsingDirective:
1196 return false;
1197
1198 case clang::DeclarationName::CXXConstructorName:
1199 case clang::DeclarationName::CXXDestructorName:
1200 case clang::DeclarationName::CXXConversionFunctionName:
1201 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1202 return Visit(TSInfo->getTypeLoc());
1203 return false;
1204
1205 case clang::DeclarationName::ObjCZeroArgSelector:
1206 case clang::DeclarationName::ObjCOneArgSelector:
1207 case clang::DeclarationName::ObjCMultiArgSelector:
1208 // FIXME: Per-identifier location info?
1209 return false;
1210 }
1211
1212 llvm_unreachable("Invalid DeclarationName::Kind!");
1213}
1214
1215bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1216 SourceRange Range) {
1217 // FIXME: This whole routine is a hack to work around the lack of proper
1218 // source information in nested-name-specifiers (PR5791). Since we do have
1219 // a beginning source location, we can visit the first component of the
1220 // nested-name-specifier, if it's a single-token component.
1221 if (!NNS)
1222 return false;
1223
1224 // Get the first component in the nested-name-specifier.
1225 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1226 NNS = Prefix;
1227
1228 switch (NNS->getKind()) {
1229 case NestedNameSpecifier::Namespace:
1230 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1231 TU));
1232
1233 case NestedNameSpecifier::NamespaceAlias:
1234 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1235 Range.getBegin(), TU));
1236
1237 case NestedNameSpecifier::TypeSpec: {
1238 // If the type has a form where we know that the beginning of the source
1239 // range matches up with a reference cursor. Visit the appropriate reference
1240 // cursor.
1241 const Type *T = NNS->getAsType();
1242 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1243 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1244 if (const TagType *Tag = dyn_cast<TagType>(T))
1245 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1246 if (const TemplateSpecializationType *TST
1247 = dyn_cast<TemplateSpecializationType>(T))
1248 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1249 break;
1250 }
1251
1252 case NestedNameSpecifier::TypeSpecWithTemplate:
1253 case NestedNameSpecifier::Global:
1254 case NestedNameSpecifier::Identifier:
1255 break;
1256 }
1257
1258 return false;
1259}
1260
1261bool
1262CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1263 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1264 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1265 Qualifiers.push_back(Qualifier);
1266
1267 while (!Qualifiers.empty()) {
1268 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1269 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1270 switch (NNS->getKind()) {
1271 case NestedNameSpecifier::Namespace:
1272 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1273 Q.getLocalBeginLoc(),
1274 TU)))
1275 return true;
1276
1277 break;
1278
1279 case NestedNameSpecifier::NamespaceAlias:
1280 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1281 Q.getLocalBeginLoc(),
1282 TU)))
1283 return true;
1284
1285 break;
1286
1287 case NestedNameSpecifier::TypeSpec:
1288 case NestedNameSpecifier::TypeSpecWithTemplate:
1289 if (Visit(Q.getTypeLoc()))
1290 return true;
1291
1292 break;
1293
1294 case NestedNameSpecifier::Global:
1295 case NestedNameSpecifier::Identifier:
1296 break;
1297 }
1298 }
1299
1300 return false;
1301}
1302
1303bool CursorVisitor::VisitTemplateParameters(
1304 const TemplateParameterList *Params) {
1305 if (!Params)
1306 return false;
1307
1308 for (TemplateParameterList::const_iterator P = Params->begin(),
1309 PEnd = Params->end();
1310 P != PEnd; ++P) {
1311 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1312 return true;
1313 }
1314
1315 return false;
1316}
1317
1318bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1319 switch (Name.getKind()) {
1320 case TemplateName::Template:
1321 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1322
1323 case TemplateName::OverloadedTemplate:
1324 // Visit the overloaded template set.
1325 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1326 return true;
1327
1328 return false;
1329
1330 case TemplateName::DependentTemplate:
1331 // FIXME: Visit nested-name-specifier.
1332 return false;
1333
1334 case TemplateName::QualifiedTemplate:
1335 // FIXME: Visit nested-name-specifier.
1336 return Visit(MakeCursorTemplateRef(
1337 Name.getAsQualifiedTemplateName()->getDecl(),
1338 Loc, TU));
1339
1340 case TemplateName::SubstTemplateTemplateParm:
1341 return Visit(MakeCursorTemplateRef(
1342 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1343 Loc, TU));
1344
1345 case TemplateName::SubstTemplateTemplateParmPack:
1346 return Visit(MakeCursorTemplateRef(
1347 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1348 Loc, TU));
1349 }
1350
1351 llvm_unreachable("Invalid TemplateName::Kind!");
1352}
1353
1354bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1355 switch (TAL.getArgument().getKind()) {
1356 case TemplateArgument::Null:
1357 case TemplateArgument::Integral:
1358 case TemplateArgument::Pack:
1359 return false;
1360
1361 case TemplateArgument::Type:
1362 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1363 return Visit(TSInfo->getTypeLoc());
1364 return false;
1365
1366 case TemplateArgument::Declaration:
1367 if (Expr *E = TAL.getSourceDeclExpression())
1368 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1369 return false;
1370
1371 case TemplateArgument::NullPtr:
1372 if (Expr *E = TAL.getSourceNullPtrExpression())
1373 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1374 return false;
1375
1376 case TemplateArgument::Expression:
1377 if (Expr *E = TAL.getSourceExpression())
1378 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1379 return false;
1380
1381 case TemplateArgument::Template:
1382 case TemplateArgument::TemplateExpansion:
1383 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1384 return true;
1385
1386 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1387 TAL.getTemplateNameLoc());
1388 }
1389
1390 llvm_unreachable("Invalid TemplateArgument::Kind!");
1391}
1392
1393bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1394 return VisitDeclContext(D);
1395}
1396
1397bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1398 return Visit(TL.getUnqualifiedLoc());
1399}
1400
1401bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1402 ASTContext &Context = AU->getASTContext();
1403
1404 // Some builtin types (such as Objective-C's "id", "sel", and
1405 // "Class") have associated declarations. Create cursors for those.
1406 QualType VisitType;
1407 switch (TL.getTypePtr()->getKind()) {
1408
1409 case BuiltinType::Void:
1410 case BuiltinType::NullPtr:
1411 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001412 case BuiltinType::OCLImage1d:
1413 case BuiltinType::OCLImage1dArray:
1414 case BuiltinType::OCLImage1dBuffer:
1415 case BuiltinType::OCLImage2d:
1416 case BuiltinType::OCLImage2dArray:
1417 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001418 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001419 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001420#define BUILTIN_TYPE(Id, SingletonId)
1421#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1422#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1423#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1424#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1425#include "clang/AST/BuiltinTypes.def"
1426 break;
1427
1428 case BuiltinType::ObjCId:
1429 VisitType = Context.getObjCIdType();
1430 break;
1431
1432 case BuiltinType::ObjCClass:
1433 VisitType = Context.getObjCClassType();
1434 break;
1435
1436 case BuiltinType::ObjCSel:
1437 VisitType = Context.getObjCSelType();
1438 break;
1439 }
1440
1441 if (!VisitType.isNull()) {
1442 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1443 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1444 TU));
1445 }
1446
1447 return false;
1448}
1449
1450bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1451 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1452}
1453
1454bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1455 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1456}
1457
1458bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1459 if (TL.isDefinition())
1460 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1461
1462 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1463}
1464
1465bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1466 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1467}
1468
1469bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1470 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1471 return true;
1472
1473 return false;
1474}
1475
1476bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1477 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1478 return true;
1479
1480 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1481 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1482 TU)))
1483 return true;
1484 }
1485
1486 return false;
1487}
1488
1489bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1490 return Visit(TL.getPointeeLoc());
1491}
1492
1493bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1494 return Visit(TL.getInnerLoc());
1495}
1496
1497bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1498 return Visit(TL.getPointeeLoc());
1499}
1500
1501bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1502 return Visit(TL.getPointeeLoc());
1503}
1504
1505bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1506 return Visit(TL.getPointeeLoc());
1507}
1508
1509bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1510 return Visit(TL.getPointeeLoc());
1511}
1512
1513bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1514 return Visit(TL.getPointeeLoc());
1515}
1516
1517bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1518 return Visit(TL.getModifiedLoc());
1519}
1520
1521bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1522 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001523 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001524 return true;
1525
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001526 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1527 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001528 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1529 return true;
1530
1531 return false;
1532}
1533
1534bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1535 if (Visit(TL.getElementLoc()))
1536 return true;
1537
1538 if (Expr *Size = TL.getSizeExpr())
1539 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1540
1541 return false;
1542}
1543
Reid Kleckner8a365022013-06-24 17:51:48 +00001544bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1545 return Visit(TL.getOriginalLoc());
1546}
1547
Reid Kleckner0503a872013-12-05 01:23:43 +00001548bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1549 return Visit(TL.getOriginalLoc());
1550}
1551
Guy Benyei11169dd2012-12-18 14:30:41 +00001552bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1553 TemplateSpecializationTypeLoc TL) {
1554 // Visit the template name.
1555 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1556 TL.getTemplateNameLoc()))
1557 return true;
1558
1559 // Visit the template arguments.
1560 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1561 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1562 return true;
1563
1564 return false;
1565}
1566
1567bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1568 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1569}
1570
1571bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1572 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1573 return Visit(TSInfo->getTypeLoc());
1574
1575 return false;
1576}
1577
1578bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1579 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1580 return Visit(TSInfo->getTypeLoc());
1581
1582 return false;
1583}
1584
1585bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1586 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1587 return true;
1588
1589 return false;
1590}
1591
1592bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1593 DependentTemplateSpecializationTypeLoc TL) {
1594 // Visit the nested-name-specifier, if there is one.
1595 if (TL.getQualifierLoc() &&
1596 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1597 return true;
1598
1599 // Visit the template arguments.
1600 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1601 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1602 return true;
1603
1604 return false;
1605}
1606
1607bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1608 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1609 return true;
1610
1611 return Visit(TL.getNamedTypeLoc());
1612}
1613
1614bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1615 return Visit(TL.getPatternLoc());
1616}
1617
1618bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1619 if (Expr *E = TL.getUnderlyingExpr())
1620 return Visit(MakeCXCursor(E, StmtParent, TU));
1621
1622 return false;
1623}
1624
1625bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1626 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1627}
1628
1629bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1630 return Visit(TL.getValueLoc());
1631}
1632
1633#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1634bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1635 return Visit##PARENT##Loc(TL); \
1636}
1637
1638DEFAULT_TYPELOC_IMPL(Complex, Type)
1639DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1640DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1641DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1642DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1643DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1644DEFAULT_TYPELOC_IMPL(Vector, Type)
1645DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1646DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1647DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1648DEFAULT_TYPELOC_IMPL(Record, TagType)
1649DEFAULT_TYPELOC_IMPL(Enum, TagType)
1650DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1651DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1652DEFAULT_TYPELOC_IMPL(Auto, Type)
1653
1654bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1655 // Visit the nested-name-specifier, if present.
1656 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1657 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1658 return true;
1659
1660 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001661 for (const auto &I : D->bases()) {
1662 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001663 return true;
1664 }
1665 }
1666
1667 return VisitTagDecl(D);
1668}
1669
1670bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001671 for (const auto *I : D->attrs())
1672 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001673 return true;
1674
1675 return false;
1676}
1677
1678//===----------------------------------------------------------------------===//
1679// Data-recursive visitor methods.
1680//===----------------------------------------------------------------------===//
1681
1682namespace {
1683#define DEF_JOB(NAME, DATA, KIND)\
1684class NAME : public VisitorJob {\
1685public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001686 NAME(const DATA *d, CXCursor parent) : \
1687 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001688 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001689 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001690};
1691
1692DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1693DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1694DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1695DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1696DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1697 ExplicitTemplateArgsVisitKind)
1698DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1699DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1700DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1701#undef DEF_JOB
1702
1703class DeclVisit : public VisitorJob {
1704public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001705 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001706 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001707 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001708 static bool classof(const VisitorJob *VJ) {
1709 return VJ->getKind() == DeclVisitKind;
1710 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001711 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001712 bool isFirst() const { return data[1] ? true : false; }
1713};
1714class TypeLocVisit : public VisitorJob {
1715public:
1716 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1717 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1718 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1719
1720 static bool classof(const VisitorJob *VJ) {
1721 return VJ->getKind() == TypeLocVisitKind;
1722 }
1723
1724 TypeLoc get() const {
1725 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001726 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001727 }
1728};
1729
1730class LabelRefVisit : public VisitorJob {
1731public:
1732 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1733 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1734 labelLoc.getPtrEncoding()) {}
1735
1736 static bool classof(const VisitorJob *VJ) {
1737 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1738 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001739 const LabelDecl *get() const {
1740 return static_cast<const LabelDecl *>(data[0]);
1741 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001742 SourceLocation getLoc() const {
1743 return SourceLocation::getFromPtrEncoding(data[1]); }
1744};
1745
1746class NestedNameSpecifierLocVisit : public VisitorJob {
1747public:
1748 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1749 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1750 Qualifier.getNestedNameSpecifier(),
1751 Qualifier.getOpaqueData()) { }
1752
1753 static bool classof(const VisitorJob *VJ) {
1754 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1755 }
1756
1757 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001758 return NestedNameSpecifierLoc(
1759 const_cast<NestedNameSpecifier *>(
1760 static_cast<const NestedNameSpecifier *>(data[0])),
1761 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001762 }
1763};
1764
1765class DeclarationNameInfoVisit : public VisitorJob {
1766public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001767 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001768 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001769 static bool classof(const VisitorJob *VJ) {
1770 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1771 }
1772 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001773 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001774 switch (S->getStmtClass()) {
1775 default:
1776 llvm_unreachable("Unhandled Stmt");
1777 case clang::Stmt::MSDependentExistsStmtClass:
1778 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1779 case Stmt::CXXDependentScopeMemberExprClass:
1780 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1781 case Stmt::DependentScopeDeclRefExprClass:
1782 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1783 }
1784 }
1785};
1786class MemberRefVisit : public VisitorJob {
1787public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001788 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001789 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1790 L.getPtrEncoding()) {}
1791 static bool classof(const VisitorJob *VJ) {
1792 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1793 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001794 const FieldDecl *get() const {
1795 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001796 }
1797 SourceLocation getLoc() const {
1798 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1799 }
1800};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001801class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001802 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001803 VisitorWorkList &WL;
1804 CXCursor Parent;
1805public:
1806 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1807 : WL(wl), Parent(parent) {}
1808
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001809 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1810 void VisitBlockExpr(const BlockExpr *B);
1811 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1812 void VisitCompoundStmt(const CompoundStmt *S);
1813 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1814 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1815 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1816 void VisitCXXNewExpr(const CXXNewExpr *E);
1817 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1818 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1819 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1820 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1821 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1822 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1823 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1824 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1825 void VisitDeclRefExpr(const DeclRefExpr *D);
1826 void VisitDeclStmt(const DeclStmt *S);
1827 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1828 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1829 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1830 void VisitForStmt(const ForStmt *FS);
1831 void VisitGotoStmt(const GotoStmt *GS);
1832 void VisitIfStmt(const IfStmt *If);
1833 void VisitInitListExpr(const InitListExpr *IE);
1834 void VisitMemberExpr(const MemberExpr *M);
1835 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1836 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1837 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1838 void VisitOverloadExpr(const OverloadExpr *E);
1839 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1840 void VisitStmt(const Stmt *S);
1841 void VisitSwitchStmt(const SwitchStmt *S);
1842 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001843 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1844 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1845 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1846 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1847 void VisitVAArgExpr(const VAArgExpr *E);
1848 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1849 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1850 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1851 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001852 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1853 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001854 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001855
Guy Benyei11169dd2012-12-18 14:30:41 +00001856private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001857 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001858 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1859 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001860 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1861 void AddStmt(const Stmt *S);
1862 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001863 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001864 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001865 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001866};
1867} // end anonyous namespace
1868
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001869void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001870 // 'S' should always be non-null, since it comes from the
1871 // statement we are visiting.
1872 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1873}
1874
1875void
1876EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1877 if (Qualifier)
1878 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1879}
1880
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001881void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001882 if (S)
1883 WL.push_back(StmtVisit(S, Parent));
1884}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001885void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001886 if (D)
1887 WL.push_back(DeclVisit(D, Parent, isFirst));
1888}
1889void EnqueueVisitor::
1890 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1891 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001892 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001893}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001894void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001895 if (D)
1896 WL.push_back(MemberRefVisit(D, L, Parent));
1897}
1898void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1899 if (TI)
1900 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1901 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001902void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001903 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001904 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001905 AddStmt(*Child);
1906 }
1907 if (size == WL.size())
1908 return;
1909 // Now reverse the entries we just added. This will match the DFS
1910 // ordering performed by the worklist.
1911 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1912 std::reverse(I, E);
1913}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001914namespace {
1915class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1916 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001917 /// \brief Process clauses with list of variables.
1918 template <typename T>
1919 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001920public:
1921 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1922#define OPENMP_CLAUSE(Name, Class) \
1923 void Visit##Class(const Class *C);
1924#include "clang/Basic/OpenMPKinds.def"
1925};
1926
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001927void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1928 Visitor->AddStmt(C->getCondition());
1929}
1930
Alexey Bataev568a8332014-03-06 06:15:19 +00001931void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1932 Visitor->AddStmt(C->getNumThreads());
1933}
1934
Alexey Bataev62c87d22014-03-21 04:51:18 +00001935void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1936 Visitor->AddStmt(C->getSafelen());
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) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001943 for (const auto *I : Node->varlists())
1944 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001945}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001946
1947void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001948 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001949}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001950void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1951 const OMPFirstprivateClause *C) {
1952 VisitOMPClauseList(C);
1953}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001954void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001955 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001956}
Alexander Musman8dba6642014-04-22 13:09:42 +00001957void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
1958 VisitOMPClauseList(C);
1959 Visitor->AddStmt(C->getStep());
1960}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00001961void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
1962 VisitOMPClauseList(C);
1963}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001964}
Alexey Bataev756c1962013-09-24 03:17:45 +00001965
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001966void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1967 unsigned size = WL.size();
1968 OMPClauseEnqueue Visitor(this);
1969 Visitor.Visit(S);
1970 if (size == WL.size())
1971 return;
1972 // Now reverse the entries we just added. This will match the DFS
1973 // ordering performed by the worklist.
1974 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1975 std::reverse(I, E);
1976}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001977void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001978 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1979}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001980void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001981 AddDecl(B->getBlockDecl());
1982}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001983void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001984 EnqueueChildren(E);
1985 AddTypeLoc(E->getTypeSourceInfo());
1986}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001987void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1988 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001989 E = S->body_rend(); I != E; ++I) {
1990 AddStmt(*I);
1991 }
1992}
1993void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001994VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001995 AddStmt(S->getSubStmt());
1996 AddDeclarationNameInfo(S);
1997 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1998 AddNestedNameSpecifierLoc(QualifierLoc);
1999}
2000
2001void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002002VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002003 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2004 AddDeclarationNameInfo(E);
2005 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2006 AddNestedNameSpecifierLoc(QualifierLoc);
2007 if (!E->isImplicitAccess())
2008 AddStmt(E->getBase());
2009}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002010void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002011 // Enqueue the initializer , if any.
2012 AddStmt(E->getInitializer());
2013 // Enqueue the array size, if any.
2014 AddStmt(E->getArraySize());
2015 // Enqueue the allocated type.
2016 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2017 // Enqueue the placement arguments.
2018 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2019 AddStmt(E->getPlacementArg(I-1));
2020}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002021void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002022 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2023 AddStmt(CE->getArg(I-1));
2024 AddStmt(CE->getCallee());
2025 AddStmt(CE->getArg(0));
2026}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002027void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2028 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002029 // Visit the name of the type being destroyed.
2030 AddTypeLoc(E->getDestroyedTypeInfo());
2031 // Visit the scope type that looks disturbingly like the nested-name-specifier
2032 // but isn't.
2033 AddTypeLoc(E->getScopeTypeInfo());
2034 // Visit the nested-name-specifier.
2035 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2036 AddNestedNameSpecifierLoc(QualifierLoc);
2037 // Visit base expression.
2038 AddStmt(E->getBase());
2039}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002040void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2041 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002042 AddTypeLoc(E->getTypeSourceInfo());
2043}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002044void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2045 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002046 EnqueueChildren(E);
2047 AddTypeLoc(E->getTypeSourceInfo());
2048}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002049void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002050 EnqueueChildren(E);
2051 if (E->isTypeOperand())
2052 AddTypeLoc(E->getTypeOperandSourceInfo());
2053}
2054
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002055void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2056 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002057 EnqueueChildren(E);
2058 AddTypeLoc(E->getTypeSourceInfo());
2059}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002060void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002061 EnqueueChildren(E);
2062 if (E->isTypeOperand())
2063 AddTypeLoc(E->getTypeOperandSourceInfo());
2064}
2065
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002066void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002067 EnqueueChildren(S);
2068 AddDecl(S->getExceptionDecl());
2069}
2070
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002071void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002072 if (DR->hasExplicitTemplateArgs()) {
2073 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2074 }
2075 WL.push_back(DeclRefExprParts(DR, Parent));
2076}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002077void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2078 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002079 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2080 AddDeclarationNameInfo(E);
2081 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2082}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002083void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002084 unsigned size = WL.size();
2085 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002086 for (const auto *D : S->decls()) {
2087 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002088 isFirst = false;
2089 }
2090 if (size == WL.size())
2091 return;
2092 // Now reverse the entries we just added. This will match the DFS
2093 // ordering performed by the worklist.
2094 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2095 std::reverse(I, E);
2096}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002097void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002098 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002099 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002100 D = E->designators_rbegin(), DEnd = E->designators_rend();
2101 D != DEnd; ++D) {
2102 if (D->isFieldDesignator()) {
2103 if (FieldDecl *Field = D->getField())
2104 AddMemberRef(Field, D->getFieldLoc());
2105 continue;
2106 }
2107 if (D->isArrayDesignator()) {
2108 AddStmt(E->getArrayIndex(*D));
2109 continue;
2110 }
2111 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2112 AddStmt(E->getArrayRangeEnd(*D));
2113 AddStmt(E->getArrayRangeStart(*D));
2114 }
2115}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002116void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002117 EnqueueChildren(E);
2118 AddTypeLoc(E->getTypeInfoAsWritten());
2119}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002120void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002121 AddStmt(FS->getBody());
2122 AddStmt(FS->getInc());
2123 AddStmt(FS->getCond());
2124 AddDecl(FS->getConditionVariable());
2125 AddStmt(FS->getInit());
2126}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002127void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002128 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2129}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002130void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002131 AddStmt(If->getElse());
2132 AddStmt(If->getThen());
2133 AddStmt(If->getCond());
2134 AddDecl(If->getConditionVariable());
2135}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002136void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002137 // We care about the syntactic form of the initializer list, only.
2138 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2139 IE = Syntactic;
2140 EnqueueChildren(IE);
2141}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002142void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002143 WL.push_back(MemberExprParts(M, Parent));
2144
2145 // If the base of the member access expression is an implicit 'this', don't
2146 // visit it.
2147 // FIXME: If we ever want to show these implicit accesses, this will be
2148 // unfortunate. However, clang_getCursor() relies on this behavior.
2149 if (!M->isImplicitAccess())
2150 AddStmt(M->getBase());
2151}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002152void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002153 AddTypeLoc(E->getEncodedTypeSourceInfo());
2154}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002155void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002156 EnqueueChildren(M);
2157 AddTypeLoc(M->getClassReceiverTypeInfo());
2158}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002159void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002160 // Visit the components of the offsetof expression.
2161 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2162 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2163 const OffsetOfNode &Node = E->getComponent(I-1);
2164 switch (Node.getKind()) {
2165 case OffsetOfNode::Array:
2166 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2167 break;
2168 case OffsetOfNode::Field:
2169 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2170 break;
2171 case OffsetOfNode::Identifier:
2172 case OffsetOfNode::Base:
2173 continue;
2174 }
2175 }
2176 // Visit the type into which we're computing the offset.
2177 AddTypeLoc(E->getTypeSourceInfo());
2178}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002179void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002180 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2181 WL.push_back(OverloadExprParts(E, Parent));
2182}
2183void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002184 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002185 EnqueueChildren(E);
2186 if (E->isArgumentType())
2187 AddTypeLoc(E->getArgumentTypeInfo());
2188}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002189void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002190 EnqueueChildren(S);
2191}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002192void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002193 AddStmt(S->getBody());
2194 AddStmt(S->getCond());
2195 AddDecl(S->getConditionVariable());
2196}
2197
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002198void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002199 AddStmt(W->getBody());
2200 AddStmt(W->getCond());
2201 AddDecl(W->getConditionVariable());
2202}
2203
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002204void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002205 for (unsigned I = E->getNumArgs(); I > 0; --I)
2206 AddTypeLoc(E->getArg(I-1));
2207}
2208
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002209void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002210 AddTypeLoc(E->getQueriedTypeSourceInfo());
2211}
2212
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002213void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002214 EnqueueChildren(E);
2215}
2216
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002217void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002218 VisitOverloadExpr(U);
2219 if (!U->isImplicitAccess())
2220 AddStmt(U->getBase());
2221}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002222void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002223 AddStmt(E->getSubExpr());
2224 AddTypeLoc(E->getWrittenTypeInfo());
2225}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002226void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002227 WL.push_back(SizeOfPackExprParts(E, Parent));
2228}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002229void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002230 // If the opaque value has a source expression, just transparently
2231 // visit that. This is useful for (e.g.) pseudo-object expressions.
2232 if (Expr *SourceExpr = E->getSourceExpr())
2233 return Visit(SourceExpr);
2234}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002235void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002236 AddStmt(E->getBody());
2237 WL.push_back(LambdaExprParts(E, Parent));
2238}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002239void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002240 // Treat the expression like its syntactic form.
2241 Visit(E->getSyntacticForm());
2242}
2243
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002244void EnqueueVisitor::VisitOMPExecutableDirective(
2245 const OMPExecutableDirective *D) {
2246 EnqueueChildren(D);
2247 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2248 E = D->clauses().end();
2249 I != E; ++I)
2250 EnqueueChildren(*I);
2251}
2252
2253void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2254 VisitOMPExecutableDirective(D);
2255}
2256
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002257void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2258 VisitOMPExecutableDirective(D);
2259}
2260
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002261void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002262 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2263}
2264
2265bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2266 if (RegionOfInterest.isValid()) {
2267 SourceRange Range = getRawCursorExtent(C);
2268 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2269 return false;
2270 }
2271 return true;
2272}
2273
2274bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2275 while (!WL.empty()) {
2276 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002277 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002278
2279 // Set the Parent field, then back to its old value once we're done.
2280 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2281
2282 switch (LI.getKind()) {
2283 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002284 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002285 if (!D)
2286 continue;
2287
2288 // For now, perform default visitation for Decls.
2289 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2290 cast<DeclVisit>(&LI)->isFirst())))
2291 return true;
2292
2293 continue;
2294 }
2295 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2296 const ASTTemplateArgumentListInfo *ArgList =
2297 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2298 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2299 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2300 Arg != ArgEnd; ++Arg) {
2301 if (VisitTemplateArgumentLoc(*Arg))
2302 return true;
2303 }
2304 continue;
2305 }
2306 case VisitorJob::TypeLocVisitKind: {
2307 // Perform default visitation for TypeLocs.
2308 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2309 return true;
2310 continue;
2311 }
2312 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002313 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002314 if (LabelStmt *stmt = LS->getStmt()) {
2315 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2316 TU))) {
2317 return true;
2318 }
2319 }
2320 continue;
2321 }
2322
2323 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2324 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2325 if (VisitNestedNameSpecifierLoc(V->get()))
2326 return true;
2327 continue;
2328 }
2329
2330 case VisitorJob::DeclarationNameInfoVisitKind: {
2331 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2332 ->get()))
2333 return true;
2334 continue;
2335 }
2336 case VisitorJob::MemberRefVisitKind: {
2337 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2338 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2339 return true;
2340 continue;
2341 }
2342 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002343 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002344 if (!S)
2345 continue;
2346
2347 // Update the current cursor.
2348 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2349 if (!IsInRegionOfInterest(Cursor))
2350 continue;
2351 switch (Visitor(Cursor, Parent, ClientData)) {
2352 case CXChildVisit_Break: return true;
2353 case CXChildVisit_Continue: break;
2354 case CXChildVisit_Recurse:
2355 if (PostChildrenVisitor)
2356 WL.push_back(PostChildrenVisit(0, Cursor));
2357 EnqueueWorkList(WL, S);
2358 break;
2359 }
2360 continue;
2361 }
2362 case VisitorJob::MemberExprPartsKind: {
2363 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002364 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002365
2366 // Visit the nested-name-specifier
2367 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2368 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2369 return true;
2370
2371 // Visit the declaration name.
2372 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2373 return true;
2374
2375 // Visit the explicitly-specified template arguments, if any.
2376 if (M->hasExplicitTemplateArgs()) {
2377 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2378 *ArgEnd = Arg + M->getNumTemplateArgs();
2379 Arg != ArgEnd; ++Arg) {
2380 if (VisitTemplateArgumentLoc(*Arg))
2381 return true;
2382 }
2383 }
2384 continue;
2385 }
2386 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002387 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002388 // Visit nested-name-specifier, if present.
2389 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2390 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2391 return true;
2392 // Visit declaration name.
2393 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2394 return true;
2395 continue;
2396 }
2397 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002398 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002399 // Visit the nested-name-specifier.
2400 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2401 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2402 return true;
2403 // Visit the declaration name.
2404 if (VisitDeclarationNameInfo(O->getNameInfo()))
2405 return true;
2406 // Visit the overloaded declaration reference.
2407 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2408 return true;
2409 continue;
2410 }
2411 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002412 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002413 NamedDecl *Pack = E->getPack();
2414 if (isa<TemplateTypeParmDecl>(Pack)) {
2415 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2416 E->getPackLoc(), TU)))
2417 return true;
2418
2419 continue;
2420 }
2421
2422 if (isa<TemplateTemplateParmDecl>(Pack)) {
2423 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2424 E->getPackLoc(), TU)))
2425 return true;
2426
2427 continue;
2428 }
2429
2430 // Non-type template parameter packs and function parameter packs are
2431 // treated like DeclRefExpr cursors.
2432 continue;
2433 }
2434
2435 case VisitorJob::LambdaExprPartsKind: {
2436 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002437 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002438 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2439 CEnd = E->explicit_capture_end();
2440 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002441 // FIXME: Lambda init-captures.
2442 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002443 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002444
Guy Benyei11169dd2012-12-18 14:30:41 +00002445 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2446 C->getLocation(),
2447 TU)))
2448 return true;
2449 }
2450
2451 // Visit parameters and return type, if present.
2452 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2453 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2454 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2455 // Visit the whole type.
2456 if (Visit(TL))
2457 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002458 } else if (FunctionProtoTypeLoc Proto =
2459 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002460 if (E->hasExplicitParameters()) {
2461 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002462 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2463 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002464 return true;
2465 } else {
2466 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002467 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002468 return true;
2469 }
2470 }
2471 }
2472 break;
2473 }
2474
2475 case VisitorJob::PostChildrenVisitKind:
2476 if (PostChildrenVisitor(Parent, ClientData))
2477 return true;
2478 break;
2479 }
2480 }
2481 return false;
2482}
2483
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002484bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002485 VisitorWorkList *WL = 0;
2486 if (!WorkListFreeList.empty()) {
2487 WL = WorkListFreeList.back();
2488 WL->clear();
2489 WorkListFreeList.pop_back();
2490 }
2491 else {
2492 WL = new VisitorWorkList();
2493 WorkListCache.push_back(WL);
2494 }
2495 EnqueueWorkList(*WL, S);
2496 bool result = RunVisitorWorkList(*WL);
2497 WorkListFreeList.push_back(WL);
2498 return result;
2499}
2500
2501namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002502typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002503RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2504 const DeclarationNameInfo &NI,
2505 const SourceRange &QLoc,
2506 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2507 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2508 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2509 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2510
2511 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2512
2513 RefNamePieces Pieces;
2514
2515 if (WantQualifier && QLoc.isValid())
2516 Pieces.push_back(QLoc);
2517
2518 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2519 Pieces.push_back(NI.getLoc());
2520
2521 if (WantTemplateArgs && TemplateArgs)
2522 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2523 TemplateArgs->RAngleLoc));
2524
2525 if (Kind == DeclarationName::CXXOperatorName) {
2526 Pieces.push_back(SourceLocation::getFromRawEncoding(
2527 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2528 Pieces.push_back(SourceLocation::getFromRawEncoding(
2529 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2530 }
2531
2532 if (WantSinglePiece) {
2533 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2534 Pieces.clear();
2535 Pieces.push_back(R);
2536 }
2537
2538 return Pieces;
2539}
2540}
2541
2542//===----------------------------------------------------------------------===//
2543// Misc. API hooks.
2544//===----------------------------------------------------------------------===//
2545
2546static llvm::sys::Mutex EnableMultithreadingMutex;
2547static bool EnabledMultithreading;
2548
Chad Rosier05c71aa2013-03-27 18:28:23 +00002549static void fatal_error_handler(void *user_data, const std::string& reason,
2550 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002551 // Write the result out to stderr avoiding errs() because raw_ostreams can
2552 // call report_fatal_error.
2553 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2554 ::abort();
2555}
2556
2557extern "C" {
2558CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2559 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002560 // We use crash recovery to make some of our APIs more reliable, implicitly
2561 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002562 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2563 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002564
2565 // Enable support for multithreading in LLVM.
2566 {
2567 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2568 if (!EnabledMultithreading) {
2569 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2570 llvm::llvm_start_multithreaded();
2571 EnabledMultithreading = true;
2572 }
2573 }
2574
2575 CIndexer *CIdxr = new CIndexer();
2576 if (excludeDeclarationsFromPCH)
2577 CIdxr->setOnlyLocalDecls();
2578 if (displayDiagnostics)
2579 CIdxr->setDisplayDiagnostics();
2580
2581 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2582 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2583 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2584 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2585 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2586 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2587
2588 return CIdxr;
2589}
2590
2591void clang_disposeIndex(CXIndex CIdx) {
2592 if (CIdx)
2593 delete static_cast<CIndexer *>(CIdx);
2594}
2595
2596void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2597 if (CIdx)
2598 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2599}
2600
2601unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2602 if (CIdx)
2603 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2604 return 0;
2605}
2606
2607void clang_toggleCrashRecovery(unsigned isEnabled) {
2608 if (isEnabled)
2609 llvm::CrashRecoveryContext::Enable();
2610 else
2611 llvm::CrashRecoveryContext::Disable();
2612}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002613
Guy Benyei11169dd2012-12-18 14:30:41 +00002614CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2615 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002616 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002617 enum CXErrorCode Result =
2618 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002619 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002620 assert((TU && Result == CXError_Success) ||
2621 (!TU && Result != CXError_Success));
2622 return TU;
2623}
2624
2625enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2626 const char *ast_filename,
2627 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002628 if (out_TU)
2629 *out_TU = NULL;
2630
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002631 if (!CIdx || !ast_filename || !out_TU)
2632 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002633
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002634 LOG_FUNC_SECTION {
2635 *Log << ast_filename;
2636 }
2637
Guy Benyei11169dd2012-12-18 14:30:41 +00002638 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2639 FileSystemOptions FileSystemOpts;
2640
2641 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002642 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002643 CXXIdx->getOnlyLocalDecls(), None,
2644 /*CaptureDiagnostics=*/true,
2645 /*AllowPCHWithCompilerErrors=*/true,
2646 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002647 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2648 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002649}
2650
2651unsigned clang_defaultEditingTranslationUnitOptions() {
2652 return CXTranslationUnit_PrecompiledPreamble |
2653 CXTranslationUnit_CacheCompletionResults;
2654}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002655
Guy Benyei11169dd2012-12-18 14:30:41 +00002656CXTranslationUnit
2657clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2658 const char *source_filename,
2659 int num_command_line_args,
2660 const char * const *command_line_args,
2661 unsigned num_unsaved_files,
2662 struct CXUnsavedFile *unsaved_files) {
2663 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2664 return clang_parseTranslationUnit(CIdx, source_filename,
2665 command_line_args, num_command_line_args,
2666 unsaved_files, num_unsaved_files,
2667 Options);
2668}
2669
2670struct ParseTranslationUnitInfo {
2671 CXIndex CIdx;
2672 const char *source_filename;
2673 const char *const *command_line_args;
2674 int num_command_line_args;
2675 struct CXUnsavedFile *unsaved_files;
2676 unsigned num_unsaved_files;
2677 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002678 CXTranslationUnit *out_TU;
2679 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002680};
2681static void clang_parseTranslationUnit_Impl(void *UserData) {
2682 ParseTranslationUnitInfo *PTUI =
2683 static_cast<ParseTranslationUnitInfo*>(UserData);
2684 CXIndex CIdx = PTUI->CIdx;
2685 const char *source_filename = PTUI->source_filename;
2686 const char * const *command_line_args = PTUI->command_line_args;
2687 int num_command_line_args = PTUI->num_command_line_args;
2688 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2689 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2690 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002691 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002692
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002693 // Set up the initial return values.
2694 if (out_TU)
2695 *out_TU = NULL;
2696 PTUI->result = CXError_Failure;
2697
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002698 // Check arguments.
2699 if (!CIdx || !out_TU ||
2700 (unsaved_files == NULL && num_unsaved_files != 0)) {
2701 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002702 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002703 }
2704
Guy Benyei11169dd2012-12-18 14:30:41 +00002705 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2706
2707 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2708 setThreadBackgroundPriority();
2709
2710 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2711 // FIXME: Add a flag for modules.
2712 TranslationUnitKind TUKind
2713 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002714 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002715 = options & CXTranslationUnit_CacheCompletionResults;
2716 bool IncludeBriefCommentsInCodeCompletion
2717 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2718 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2719 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2720
2721 // Configure the diagnostics.
2722 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002723 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002724
2725 // Recover resources if we crash before exiting this function.
2726 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2727 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2728 DiagCleanup(Diags.getPtr());
2729
Ahmed Charlesb8984322014-03-07 20:03:18 +00002730 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2731 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002732
2733 // Recover resources if we crash before exiting this function.
2734 llvm::CrashRecoveryContextCleanupRegistrar<
2735 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2736
2737 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2738 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2739 const llvm::MemoryBuffer *Buffer
2740 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2741 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2742 Buffer));
2743 }
2744
Ahmed Charlesb8984322014-03-07 20:03:18 +00002745 std::unique_ptr<std::vector<const char *>> Args(
2746 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002747
2748 // Recover resources if we crash before exiting this method.
2749 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2750 ArgsCleanup(Args.get());
2751
2752 // Since the Clang C library is primarily used by batch tools dealing with
2753 // (often very broken) source code, where spell-checking can have a
2754 // significant negative impact on performance (particularly when
2755 // precompiled headers are involved), we disable it by default.
2756 // Only do this if we haven't found a spell-checking-related argument.
2757 bool FoundSpellCheckingArgument = false;
2758 for (int I = 0; I != num_command_line_args; ++I) {
2759 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2760 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2761 FoundSpellCheckingArgument = true;
2762 break;
2763 }
2764 }
2765 if (!FoundSpellCheckingArgument)
2766 Args->push_back("-fno-spell-checking");
2767
2768 Args->insert(Args->end(), command_line_args,
2769 command_line_args + num_command_line_args);
2770
2771 // The 'source_filename' argument is optional. If the caller does not
2772 // specify it then it is assumed that the source file is specified
2773 // in the actual argument list.
2774 // Put the source file after command_line_args otherwise if '-x' flag is
2775 // present it will be unused.
2776 if (source_filename)
2777 Args->push_back(source_filename);
2778
2779 // Do we need the detailed preprocessing record?
2780 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2781 Args->push_back("-Xclang");
2782 Args->push_back("-detailed-preprocessing-record");
2783 }
2784
2785 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002786 std::unique_ptr<ASTUnit> ErrUnit;
2787 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002788 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002789 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2790 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2791 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2792 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2793 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2794 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002795
2796 if (NumErrors != Diags->getClient()->getNumErrors()) {
2797 // Make sure to check that 'Unit' is non-NULL.
2798 if (CXXIdx->getDisplayDiagnostics())
2799 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2800 }
2801
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002802 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2803 PTUI->result = CXError_ASTReadError;
2804 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002805 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002806 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2807 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002808}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002809
2810CXTranslationUnit
2811clang_parseTranslationUnit(CXIndex CIdx,
2812 const char *source_filename,
2813 const char *const *command_line_args,
2814 int num_command_line_args,
2815 struct CXUnsavedFile *unsaved_files,
2816 unsigned num_unsaved_files,
2817 unsigned options) {
2818 CXTranslationUnit TU;
2819 enum CXErrorCode Result = clang_parseTranslationUnit2(
2820 CIdx, source_filename, command_line_args, num_command_line_args,
2821 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002822 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002823 assert((TU && Result == CXError_Success) ||
2824 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002825 return TU;
2826}
2827
2828enum CXErrorCode clang_parseTranslationUnit2(
2829 CXIndex CIdx,
2830 const char *source_filename,
2831 const char *const *command_line_args,
2832 int num_command_line_args,
2833 struct CXUnsavedFile *unsaved_files,
2834 unsigned num_unsaved_files,
2835 unsigned options,
2836 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002837 LOG_FUNC_SECTION {
2838 *Log << source_filename << ": ";
2839 for (int i = 0; i != num_command_line_args; ++i)
2840 *Log << command_line_args[i] << " ";
2841 }
2842
Guy Benyei11169dd2012-12-18 14:30:41 +00002843 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2844 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002845 num_unsaved_files, options, out_TU,
2846 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002847 llvm::CrashRecoveryContext CRC;
2848
2849 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2850 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2851 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2852 fprintf(stderr, " 'command_line_args' : [");
2853 for (int i = 0; i != num_command_line_args; ++i) {
2854 if (i)
2855 fprintf(stderr, ", ");
2856 fprintf(stderr, "'%s'", command_line_args[i]);
2857 }
2858 fprintf(stderr, "],\n");
2859 fprintf(stderr, " 'unsaved_files' : [");
2860 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2861 if (i)
2862 fprintf(stderr, ", ");
2863 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2864 unsaved_files[i].Length);
2865 }
2866 fprintf(stderr, "],\n");
2867 fprintf(stderr, " 'options' : %d,\n", options);
2868 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002869
2870 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002871 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002872 if (CXTranslationUnit *TU = PTUI.out_TU)
2873 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002874 }
2875
2876 return PTUI.result;
2877}
2878
2879unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2880 return CXSaveTranslationUnit_None;
2881}
2882
2883namespace {
2884
2885struct SaveTranslationUnitInfo {
2886 CXTranslationUnit TU;
2887 const char *FileName;
2888 unsigned options;
2889 CXSaveError result;
2890};
2891
2892}
2893
2894static void clang_saveTranslationUnit_Impl(void *UserData) {
2895 SaveTranslationUnitInfo *STUI =
2896 static_cast<SaveTranslationUnitInfo*>(UserData);
2897
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002898 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002899 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2900 setThreadBackgroundPriority();
2901
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002902 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002903 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2904}
2905
2906int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2907 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002908 LOG_FUNC_SECTION {
2909 *Log << TU << ' ' << FileName;
2910 }
2911
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002912 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002913 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002914 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002915 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002916
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002917 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002918 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2919 if (!CXXUnit->hasSema())
2920 return CXSaveError_InvalidTU;
2921
2922 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2923
2924 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2925 getenv("LIBCLANG_NOTHREADS")) {
2926 clang_saveTranslationUnit_Impl(&STUI);
2927
2928 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2929 PrintLibclangResourceUsage(TU);
2930
2931 return STUI.result;
2932 }
2933
2934 // We have an AST that has invalid nodes due to compiler errors.
2935 // Use a crash recovery thread for protection.
2936
2937 llvm::CrashRecoveryContext CRC;
2938
2939 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2940 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2941 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2942 fprintf(stderr, " 'options' : %d,\n", options);
2943 fprintf(stderr, "}\n");
2944
2945 return CXSaveError_Unknown;
2946
2947 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2948 PrintLibclangResourceUsage(TU);
2949 }
2950
2951 return STUI.result;
2952}
2953
2954void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2955 if (CTUnit) {
2956 // If the translation unit has been marked as unsafe to free, just discard
2957 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002958 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2959 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002960 return;
2961
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002962 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002963 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002964 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2965 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002966 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002967 delete CTUnit;
2968 }
2969}
2970
2971unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2972 return CXReparse_None;
2973}
2974
2975struct ReparseTranslationUnitInfo {
2976 CXTranslationUnit TU;
2977 unsigned num_unsaved_files;
2978 struct CXUnsavedFile *unsaved_files;
2979 unsigned options;
2980 int result;
2981};
2982
2983static void clang_reparseTranslationUnit_Impl(void *UserData) {
2984 ReparseTranslationUnitInfo *RTUI =
2985 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002986 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002987
Guy Benyei11169dd2012-12-18 14:30:41 +00002988 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002989 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2990 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2991 unsigned options = RTUI->options;
2992 (void) options;
2993
2994 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002995 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002996 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002997 RTUI->result = CXError_InvalidArguments;
2998 return;
2999 }
3000 if (unsaved_files == NULL && num_unsaved_files != 0) {
3001 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003002 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003003 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003004
3005 // Reset the associated diagnostics.
3006 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3007 TU->Diagnostics = 0;
3008
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003009 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003010 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3011 setThreadBackgroundPriority();
3012
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003013 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003014 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003015
3016 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3017 new std::vector<ASTUnit::RemappedFile>());
3018
Guy Benyei11169dd2012-12-18 14:30:41 +00003019 // Recover resources if we crash before exiting this function.
3020 llvm::CrashRecoveryContextCleanupRegistrar<
3021 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3022
3023 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3024 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3025 const llvm::MemoryBuffer *Buffer
3026 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3027 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3028 Buffer));
3029 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003030
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003031 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003032 RTUI->result = CXError_Success;
3033 else if (isASTReadError(CXXUnit))
3034 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003035}
3036
3037int clang_reparseTranslationUnit(CXTranslationUnit TU,
3038 unsigned num_unsaved_files,
3039 struct CXUnsavedFile *unsaved_files,
3040 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003041 LOG_FUNC_SECTION {
3042 *Log << TU;
3043 }
3044
Guy Benyei11169dd2012-12-18 14:30:41 +00003045 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003046 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003047
3048 if (getenv("LIBCLANG_NOTHREADS")) {
3049 clang_reparseTranslationUnit_Impl(&RTUI);
3050 return RTUI.result;
3051 }
3052
3053 llvm::CrashRecoveryContext CRC;
3054
3055 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3056 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003057 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003058 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003059 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3060 PrintLibclangResourceUsage(TU);
3061
3062 return RTUI.result;
3063}
3064
3065
3066CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003067 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003068 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003069 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003070 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003071
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003072 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003073 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003074}
3075
3076CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003077 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003078 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003079 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003080 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003081
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003082 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003083 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3084}
3085
3086} // end: extern "C"
3087
3088//===----------------------------------------------------------------------===//
3089// CXFile Operations.
3090//===----------------------------------------------------------------------===//
3091
3092extern "C" {
3093CXString clang_getFileName(CXFile SFile) {
3094 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003095 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003096
3097 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003098 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003099}
3100
3101time_t clang_getFileTime(CXFile SFile) {
3102 if (!SFile)
3103 return 0;
3104
3105 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3106 return FEnt->getModificationTime();
3107}
3108
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003109CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003110 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003111 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003112 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003113 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003114
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003115 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003116
3117 FileManager &FMgr = CXXUnit->getFileManager();
3118 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3119}
3120
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003121unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3122 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003123 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003124 LOG_BAD_TU(TU);
3125 return 0;
3126 }
3127
3128 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003129 return 0;
3130
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003131 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003132 FileEntry *FEnt = static_cast<FileEntry *>(file);
3133 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3134 .isFileMultipleIncludeGuarded(FEnt);
3135}
3136
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003137int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3138 if (!file || !outID)
3139 return 1;
3140
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003141 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003142 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3143 outID->data[0] = ID.getDevice();
3144 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003145 outID->data[2] = FEnt->getModificationTime();
3146 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003147}
3148
Guy Benyei11169dd2012-12-18 14:30:41 +00003149} // end: extern "C"
3150
3151//===----------------------------------------------------------------------===//
3152// CXCursor Operations.
3153//===----------------------------------------------------------------------===//
3154
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003155static const Decl *getDeclFromExpr(const Stmt *E) {
3156 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003157 return getDeclFromExpr(CE->getSubExpr());
3158
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003159 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003160 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003161 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003162 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003163 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003164 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003165 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003166 if (PRE->isExplicitProperty())
3167 return PRE->getExplicitProperty();
3168 // It could be messaging both getter and setter as in:
3169 // ++myobj.myprop;
3170 // in which case prefer to associate the setter since it is less obvious
3171 // from inspecting the source that the setter is going to get called.
3172 if (PRE->isMessagingSetter())
3173 return PRE->getImplicitPropertySetter();
3174 return PRE->getImplicitPropertyGetter();
3175 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003176 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003177 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003178 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003179 if (Expr *Src = OVE->getSourceExpr())
3180 return getDeclFromExpr(Src);
3181
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003182 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003183 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003184 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003185 if (!CE->isElidable())
3186 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003187 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003188 return OME->getMethodDecl();
3189
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003190 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003191 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003192 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003193 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3194 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003195 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003196 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3197 isa<ParmVarDecl>(SizeOfPack->getPack()))
3198 return SizeOfPack->getPack();
3199
3200 return 0;
3201}
3202
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003203static SourceLocation getLocationFromExpr(const Expr *E) {
3204 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003205 return getLocationFromExpr(CE->getSubExpr());
3206
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003207 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003208 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003209 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003210 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003211 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003212 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003213 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003214 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003215 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003216 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003217 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003218 return PropRef->getLocation();
3219
3220 return E->getLocStart();
3221}
3222
3223extern "C" {
3224
3225unsigned clang_visitChildren(CXCursor parent,
3226 CXCursorVisitor visitor,
3227 CXClientData client_data) {
3228 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3229 /*VisitPreprocessorLast=*/false);
3230 return CursorVis.VisitChildren(parent);
3231}
3232
3233#ifndef __has_feature
3234#define __has_feature(x) 0
3235#endif
3236#if __has_feature(blocks)
3237typedef enum CXChildVisitResult
3238 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3239
3240static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3241 CXClientData client_data) {
3242 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3243 return block(cursor, parent);
3244}
3245#else
3246// If we are compiled with a compiler that doesn't have native blocks support,
3247// define and call the block manually, so the
3248typedef struct _CXChildVisitResult
3249{
3250 void *isa;
3251 int flags;
3252 int reserved;
3253 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3254 CXCursor);
3255} *CXCursorVisitorBlock;
3256
3257static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3258 CXClientData client_data) {
3259 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3260 return block->invoke(block, cursor, parent);
3261}
3262#endif
3263
3264
3265unsigned clang_visitChildrenWithBlock(CXCursor parent,
3266 CXCursorVisitorBlock block) {
3267 return clang_visitChildren(parent, visitWithBlock, block);
3268}
3269
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003270static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003271 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003272 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003273
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003274 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003275 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003276 if (const ObjCPropertyImplDecl *PropImpl =
3277 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003278 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003279 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003280
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003281 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003282 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003283 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003284
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003285 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003286 }
3287
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003288 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003289 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003290
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003291 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003292 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3293 // and returns different names. NamedDecl returns the class name and
3294 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003295 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003296
3297 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003298 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003299
3300 SmallString<1024> S;
3301 llvm::raw_svector_ostream os(S);
3302 ND->printName(os);
3303
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003304 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003305}
3306
3307CXString clang_getCursorSpelling(CXCursor C) {
3308 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003309 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003310
3311 if (clang_isReference(C.kind)) {
3312 switch (C.kind) {
3313 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003314 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003315 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003316 }
3317 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003318 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003319 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003320 }
3321 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003322 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003323 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003324 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003325 }
3326 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003327 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003328 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003329 }
3330 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003331 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003332 assert(Type && "Missing type decl");
3333
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003334 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003335 getAsString());
3336 }
3337 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003338 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003339 assert(Template && "Missing template decl");
3340
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003341 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003342 }
3343
3344 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003345 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003346 assert(NS && "Missing namespace decl");
3347
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003348 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 }
3350
3351 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003352 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003353 assert(Field && "Missing member decl");
3354
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003355 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003356 }
3357
3358 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003359 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003360 assert(Label && "Missing label");
3361
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003362 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003363 }
3364
3365 case CXCursor_OverloadedDeclRef: {
3366 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003367 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3368 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003369 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003370 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003371 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003372 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003373 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003374 OverloadedTemplateStorage *Ovl
3375 = Storage.get<OverloadedTemplateStorage*>();
3376 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003377 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003378 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003379 }
3380
3381 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003382 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003383 assert(Var && "Missing variable decl");
3384
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003385 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003386 }
3387
3388 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003389 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003390 }
3391 }
3392
3393 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003394 const Expr *E = getCursorExpr(C);
3395
3396 if (C.kind == CXCursor_ObjCStringLiteral ||
3397 C.kind == CXCursor_StringLiteral) {
3398 const StringLiteral *SLit;
3399 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3400 SLit = OSL->getString();
3401 } else {
3402 SLit = cast<StringLiteral>(E);
3403 }
3404 SmallString<256> Buf;
3405 llvm::raw_svector_ostream OS(Buf);
3406 SLit->outputString(OS);
3407 return cxstring::createDup(OS.str());
3408 }
3409
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003410 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003411 if (D)
3412 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003413 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003414 }
3415
3416 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003417 const Stmt *S = getCursorStmt(C);
3418 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003419 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003420
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003421 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003422 }
3423
3424 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003425 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003426 ->getNameStart());
3427
3428 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003429 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003430 ->getNameStart());
3431
3432 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003433 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003434
3435 if (clang_isDeclaration(C.kind))
3436 return getDeclSpelling(getCursorDecl(C));
3437
3438 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003439 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003440 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003441 }
3442
3443 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003444 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003445 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003446 }
3447
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003448 if (C.kind == CXCursor_PackedAttr) {
3449 return cxstring::createRef("packed");
3450 }
3451
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003452 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003453}
3454
3455CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3456 unsigned pieceIndex,
3457 unsigned options) {
3458 if (clang_Cursor_isNull(C))
3459 return clang_getNullRange();
3460
3461 ASTContext &Ctx = getCursorContext(C);
3462
3463 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003464 const Stmt *S = getCursorStmt(C);
3465 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003466 if (pieceIndex > 0)
3467 return clang_getNullRange();
3468 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3469 }
3470
3471 return clang_getNullRange();
3472 }
3473
3474 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003475 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003476 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3477 if (pieceIndex >= ME->getNumSelectorLocs())
3478 return clang_getNullRange();
3479 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3480 }
3481 }
3482
3483 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3484 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003485 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003486 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3487 if (pieceIndex >= MD->getNumSelectorLocs())
3488 return clang_getNullRange();
3489 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3490 }
3491 }
3492
3493 if (C.kind == CXCursor_ObjCCategoryDecl ||
3494 C.kind == CXCursor_ObjCCategoryImplDecl) {
3495 if (pieceIndex > 0)
3496 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003497 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003498 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3499 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003500 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003501 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3502 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3503 }
3504
3505 if (C.kind == CXCursor_ModuleImportDecl) {
3506 if (pieceIndex > 0)
3507 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003508 if (const ImportDecl *ImportD =
3509 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003510 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3511 if (!Locs.empty())
3512 return cxloc::translateSourceRange(Ctx,
3513 SourceRange(Locs.front(), Locs.back()));
3514 }
3515 return clang_getNullRange();
3516 }
3517
3518 // FIXME: A CXCursor_InclusionDirective should give the location of the
3519 // filename, but we don't keep track of this.
3520
3521 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3522 // but we don't keep track of this.
3523
3524 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3525 // but we don't keep track of this.
3526
3527 // Default handling, give the location of the cursor.
3528
3529 if (pieceIndex > 0)
3530 return clang_getNullRange();
3531
3532 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3533 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3534 return cxloc::translateSourceRange(Ctx, Loc);
3535}
3536
3537CXString clang_getCursorDisplayName(CXCursor C) {
3538 if (!clang_isDeclaration(C.kind))
3539 return clang_getCursorSpelling(C);
3540
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003541 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003542 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003543 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003544
3545 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003546 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003547 D = FunTmpl->getTemplatedDecl();
3548
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003549 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003550 SmallString<64> Str;
3551 llvm::raw_svector_ostream OS(Str);
3552 OS << *Function;
3553 if (Function->getPrimaryTemplate())
3554 OS << "<>";
3555 OS << "(";
3556 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3557 if (I)
3558 OS << ", ";
3559 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3560 }
3561
3562 if (Function->isVariadic()) {
3563 if (Function->getNumParams())
3564 OS << ", ";
3565 OS << "...";
3566 }
3567 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003568 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003569 }
3570
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003571 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003572 SmallString<64> Str;
3573 llvm::raw_svector_ostream OS(Str);
3574 OS << *ClassTemplate;
3575 OS << "<";
3576 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3577 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3578 if (I)
3579 OS << ", ";
3580
3581 NamedDecl *Param = Params->getParam(I);
3582 if (Param->getIdentifier()) {
3583 OS << Param->getIdentifier()->getName();
3584 continue;
3585 }
3586
3587 // There is no parameter name, which makes this tricky. Try to come up
3588 // with something useful that isn't too long.
3589 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3590 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3591 else if (NonTypeTemplateParmDecl *NTTP
3592 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3593 OS << NTTP->getType().getAsString(Policy);
3594 else
3595 OS << "template<...> class";
3596 }
3597
3598 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003599 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003600 }
3601
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003602 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003603 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3604 // If the type was explicitly written, use that.
3605 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003606 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003607
Benjamin Kramer9170e912013-02-22 15:46:01 +00003608 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003609 llvm::raw_svector_ostream OS(Str);
3610 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003611 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003612 ClassSpec->getTemplateArgs().data(),
3613 ClassSpec->getTemplateArgs().size(),
3614 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003615 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003616 }
3617
3618 return clang_getCursorSpelling(C);
3619}
3620
3621CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3622 switch (Kind) {
3623 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003624 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003626 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003628 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003630 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003632 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003633 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003634 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003636 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003638 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003639 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003640 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003642 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003643 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003644 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003646 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003648 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003650 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003652 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003654 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003656 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003658 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003660 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003662 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003664 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003666 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003668 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003670 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003672 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003751 case CXCursor_ObjCSelfExpr:
3752 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003869 case CXCursor_PackedAttr:
3870 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003910 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003914 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003916 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003918 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003919 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003920 return cxstring::createRef("OMPParallelDirective");
3921 case CXCursor_OMPSimdDirective:
3922 return cxstring::createRef("OMPSimdDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 }
3924
3925 llvm_unreachable("Unhandled CXCursorKind");
3926}
3927
3928struct GetCursorData {
3929 SourceLocation TokenBeginLoc;
3930 bool PointsAtMacroArgExpansion;
3931 bool VisitedObjCPropertyImplDecl;
3932 SourceLocation VisitedDeclaratorDeclStartLoc;
3933 CXCursor &BestCursor;
3934
3935 GetCursorData(SourceManager &SM,
3936 SourceLocation tokenBegin, CXCursor &outputCursor)
3937 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3938 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3939 VisitedObjCPropertyImplDecl = false;
3940 }
3941};
3942
3943static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3944 CXCursor parent,
3945 CXClientData client_data) {
3946 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3947 CXCursor *BestCursor = &Data->BestCursor;
3948
3949 // If we point inside a macro argument we should provide info of what the
3950 // token is so use the actual cursor, don't replace it with a macro expansion
3951 // cursor.
3952 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3953 return CXChildVisit_Recurse;
3954
3955 if (clang_isDeclaration(cursor.kind)) {
3956 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003957 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003958 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3959 if (MD->isImplicit())
3960 return CXChildVisit_Break;
3961
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003962 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3964 // Check that when we have multiple @class references in the same line,
3965 // that later ones do not override the previous ones.
3966 // If we have:
3967 // @class Foo, Bar;
3968 // source ranges for both start at '@', so 'Bar' will end up overriding
3969 // 'Foo' even though the cursor location was at 'Foo'.
3970 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3971 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003972 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3974 if (PrevID != ID &&
3975 !PrevID->isThisDeclarationADefinition() &&
3976 !ID->isThisDeclarationADefinition())
3977 return CXChildVisit_Break;
3978 }
3979
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003980 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3982 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3983 // Check that when we have multiple declarators in the same line,
3984 // that later ones do not override the previous ones.
3985 // If we have:
3986 // int Foo, Bar;
3987 // source ranges for both start at 'int', so 'Bar' will end up overriding
3988 // 'Foo' even though the cursor location was at 'Foo'.
3989 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3990 return CXChildVisit_Break;
3991 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3992
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003993 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003994 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3995 (void)PropImp;
3996 // Check that when we have multiple @synthesize in the same line,
3997 // that later ones do not override the previous ones.
3998 // If we have:
3999 // @synthesize Foo, Bar;
4000 // source ranges for both start at '@', so 'Bar' will end up overriding
4001 // 'Foo' even though the cursor location was at 'Foo'.
4002 if (Data->VisitedObjCPropertyImplDecl)
4003 return CXChildVisit_Break;
4004 Data->VisitedObjCPropertyImplDecl = true;
4005 }
4006 }
4007
4008 if (clang_isExpression(cursor.kind) &&
4009 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004010 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004011 // Avoid having the cursor of an expression replace the declaration cursor
4012 // when the expression source range overlaps the declaration range.
4013 // This can happen for C++ constructor expressions whose range generally
4014 // include the variable declaration, e.g.:
4015 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4016 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4017 D->getLocation() == Data->TokenBeginLoc)
4018 return CXChildVisit_Break;
4019 }
4020 }
4021
4022 // If our current best cursor is the construction of a temporary object,
4023 // don't replace that cursor with a type reference, because we want
4024 // clang_getCursor() to point at the constructor.
4025 if (clang_isExpression(BestCursor->kind) &&
4026 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4027 cursor.kind == CXCursor_TypeRef) {
4028 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4029 // as having the actual point on the type reference.
4030 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4031 return CXChildVisit_Recurse;
4032 }
4033
4034 *BestCursor = cursor;
4035 return CXChildVisit_Recurse;
4036}
4037
4038CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004039 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004040 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004041 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004042 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004043
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004044 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004045 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4046
4047 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4048 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4049
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004050 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 CXFile SearchFile;
4052 unsigned SearchLine, SearchColumn;
4053 CXFile ResultFile;
4054 unsigned ResultLine, ResultColumn;
4055 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4056 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4057 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4058
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004059 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4060 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 &ResultColumn, 0);
4062 SearchFileName = clang_getFileName(SearchFile);
4063 ResultFileName = clang_getFileName(ResultFile);
4064 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4065 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004066 *Log << llvm::format("(%s:%d:%d) = %s",
4067 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4068 clang_getCString(KindSpelling))
4069 << llvm::format("(%s:%d:%d):%s%s",
4070 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4071 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004072 clang_disposeString(SearchFileName);
4073 clang_disposeString(ResultFileName);
4074 clang_disposeString(KindSpelling);
4075 clang_disposeString(USR);
4076
4077 CXCursor Definition = clang_getCursorDefinition(Result);
4078 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4079 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4080 CXString DefinitionKindSpelling
4081 = clang_getCursorKindSpelling(Definition.kind);
4082 CXFile DefinitionFile;
4083 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004084 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004085 &DefinitionLine, &DefinitionColumn, 0);
4086 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004087 *Log << llvm::format(" -> %s(%s:%d:%d)",
4088 clang_getCString(DefinitionKindSpelling),
4089 clang_getCString(DefinitionFileName),
4090 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004091 clang_disposeString(DefinitionFileName);
4092 clang_disposeString(DefinitionKindSpelling);
4093 }
4094 }
4095
4096 return Result;
4097}
4098
4099CXCursor clang_getNullCursor(void) {
4100 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4101}
4102
4103unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004104 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4105 // can't set consistently. For example, when visiting a DeclStmt we will set
4106 // it but we don't set it on the result of clang_getCursorDefinition for
4107 // a reference of the same declaration.
4108 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4109 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4110 // to provide that kind of info.
4111 if (clang_isDeclaration(X.kind))
4112 X.data[1] = 0;
4113 if (clang_isDeclaration(Y.kind))
4114 Y.data[1] = 0;
4115
Guy Benyei11169dd2012-12-18 14:30:41 +00004116 return X == Y;
4117}
4118
4119unsigned clang_hashCursor(CXCursor C) {
4120 unsigned Index = 0;
4121 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4122 Index = 1;
4123
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004124 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004125 std::make_pair(C.kind, C.data[Index]));
4126}
4127
4128unsigned clang_isInvalid(enum CXCursorKind K) {
4129 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4130}
4131
4132unsigned clang_isDeclaration(enum CXCursorKind K) {
4133 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4134 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4135}
4136
4137unsigned clang_isReference(enum CXCursorKind K) {
4138 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4139}
4140
4141unsigned clang_isExpression(enum CXCursorKind K) {
4142 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4143}
4144
4145unsigned clang_isStatement(enum CXCursorKind K) {
4146 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4147}
4148
4149unsigned clang_isAttribute(enum CXCursorKind K) {
4150 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4151}
4152
4153unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4154 return K == CXCursor_TranslationUnit;
4155}
4156
4157unsigned clang_isPreprocessing(enum CXCursorKind K) {
4158 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4159}
4160
4161unsigned clang_isUnexposed(enum CXCursorKind K) {
4162 switch (K) {
4163 case CXCursor_UnexposedDecl:
4164 case CXCursor_UnexposedExpr:
4165 case CXCursor_UnexposedStmt:
4166 case CXCursor_UnexposedAttr:
4167 return true;
4168 default:
4169 return false;
4170 }
4171}
4172
4173CXCursorKind clang_getCursorKind(CXCursor C) {
4174 return C.kind;
4175}
4176
4177CXSourceLocation clang_getCursorLocation(CXCursor C) {
4178 if (clang_isReference(C.kind)) {
4179 switch (C.kind) {
4180 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004181 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004182 = getCursorObjCSuperClassRef(C);
4183 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4184 }
4185
4186 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004187 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004188 = getCursorObjCProtocolRef(C);
4189 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4190 }
4191
4192 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004193 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004194 = getCursorObjCClassRef(C);
4195 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4196 }
4197
4198 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004199 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004200 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4201 }
4202
4203 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004204 std::pair<const TemplateDecl *, SourceLocation> P =
4205 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004206 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4207 }
4208
4209 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004210 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4212 }
4213
4214 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004215 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4217 }
4218
4219 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004220 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004221 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4222 }
4223
4224 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004225 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004226 if (!BaseSpec)
4227 return clang_getNullLocation();
4228
4229 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4230 return cxloc::translateSourceLocation(getCursorContext(C),
4231 TSInfo->getTypeLoc().getBeginLoc());
4232
4233 return cxloc::translateSourceLocation(getCursorContext(C),
4234 BaseSpec->getLocStart());
4235 }
4236
4237 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004238 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004239 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4240 }
4241
4242 case CXCursor_OverloadedDeclRef:
4243 return cxloc::translateSourceLocation(getCursorContext(C),
4244 getCursorOverloadedDeclRef(C).second);
4245
4246 default:
4247 // FIXME: Need a way to enumerate all non-reference cases.
4248 llvm_unreachable("Missed a reference kind");
4249 }
4250 }
4251
4252 if (clang_isExpression(C.kind))
4253 return cxloc::translateSourceLocation(getCursorContext(C),
4254 getLocationFromExpr(getCursorExpr(C)));
4255
4256 if (clang_isStatement(C.kind))
4257 return cxloc::translateSourceLocation(getCursorContext(C),
4258 getCursorStmt(C)->getLocStart());
4259
4260 if (C.kind == CXCursor_PreprocessingDirective) {
4261 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4262 return cxloc::translateSourceLocation(getCursorContext(C), L);
4263 }
4264
4265 if (C.kind == CXCursor_MacroExpansion) {
4266 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004267 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004268 return cxloc::translateSourceLocation(getCursorContext(C), L);
4269 }
4270
4271 if (C.kind == CXCursor_MacroDefinition) {
4272 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4273 return cxloc::translateSourceLocation(getCursorContext(C), L);
4274 }
4275
4276 if (C.kind == CXCursor_InclusionDirective) {
4277 SourceLocation L
4278 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4279 return cxloc::translateSourceLocation(getCursorContext(C), L);
4280 }
4281
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004282 if (clang_isAttribute(C.kind)) {
4283 SourceLocation L
4284 = cxcursor::getCursorAttr(C)->getLocation();
4285 return cxloc::translateSourceLocation(getCursorContext(C), L);
4286 }
4287
Guy Benyei11169dd2012-12-18 14:30:41 +00004288 if (!clang_isDeclaration(C.kind))
4289 return clang_getNullLocation();
4290
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004291 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004292 if (!D)
4293 return clang_getNullLocation();
4294
4295 SourceLocation Loc = D->getLocation();
4296 // FIXME: Multiple variables declared in a single declaration
4297 // currently lack the information needed to correctly determine their
4298 // ranges when accounting for the type-specifier. We use context
4299 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4300 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004301 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004302 if (!cxcursor::isFirstInDeclGroup(C))
4303 Loc = VD->getLocation();
4304 }
4305
4306 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004307 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004308 Loc = MD->getSelectorStartLoc();
4309
4310 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4311}
4312
4313} // end extern "C"
4314
4315CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4316 assert(TU);
4317
4318 // Guard against an invalid SourceLocation, or we may assert in one
4319 // of the following calls.
4320 if (SLoc.isInvalid())
4321 return clang_getNullCursor();
4322
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004323 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004324
4325 // Translate the given source location to make it point at the beginning of
4326 // the token under the cursor.
4327 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4328 CXXUnit->getASTContext().getLangOpts());
4329
4330 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4331 if (SLoc.isValid()) {
4332 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4333 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4334 /*VisitPreprocessorLast=*/true,
4335 /*VisitIncludedEntities=*/false,
4336 SourceLocation(SLoc));
4337 CursorVis.visitFileRegion();
4338 }
4339
4340 return Result;
4341}
4342
4343static SourceRange getRawCursorExtent(CXCursor C) {
4344 if (clang_isReference(C.kind)) {
4345 switch (C.kind) {
4346 case CXCursor_ObjCSuperClassRef:
4347 return getCursorObjCSuperClassRef(C).second;
4348
4349 case CXCursor_ObjCProtocolRef:
4350 return getCursorObjCProtocolRef(C).second;
4351
4352 case CXCursor_ObjCClassRef:
4353 return getCursorObjCClassRef(C).second;
4354
4355 case CXCursor_TypeRef:
4356 return getCursorTypeRef(C).second;
4357
4358 case CXCursor_TemplateRef:
4359 return getCursorTemplateRef(C).second;
4360
4361 case CXCursor_NamespaceRef:
4362 return getCursorNamespaceRef(C).second;
4363
4364 case CXCursor_MemberRef:
4365 return getCursorMemberRef(C).second;
4366
4367 case CXCursor_CXXBaseSpecifier:
4368 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4369
4370 case CXCursor_LabelRef:
4371 return getCursorLabelRef(C).second;
4372
4373 case CXCursor_OverloadedDeclRef:
4374 return getCursorOverloadedDeclRef(C).second;
4375
4376 case CXCursor_VariableRef:
4377 return getCursorVariableRef(C).second;
4378
4379 default:
4380 // FIXME: Need a way to enumerate all non-reference cases.
4381 llvm_unreachable("Missed a reference kind");
4382 }
4383 }
4384
4385 if (clang_isExpression(C.kind))
4386 return getCursorExpr(C)->getSourceRange();
4387
4388 if (clang_isStatement(C.kind))
4389 return getCursorStmt(C)->getSourceRange();
4390
4391 if (clang_isAttribute(C.kind))
4392 return getCursorAttr(C)->getRange();
4393
4394 if (C.kind == CXCursor_PreprocessingDirective)
4395 return cxcursor::getCursorPreprocessingDirective(C);
4396
4397 if (C.kind == CXCursor_MacroExpansion) {
4398 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004399 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004400 return TU->mapRangeFromPreamble(Range);
4401 }
4402
4403 if (C.kind == CXCursor_MacroDefinition) {
4404 ASTUnit *TU = getCursorASTUnit(C);
4405 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4406 return TU->mapRangeFromPreamble(Range);
4407 }
4408
4409 if (C.kind == CXCursor_InclusionDirective) {
4410 ASTUnit *TU = getCursorASTUnit(C);
4411 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4412 return TU->mapRangeFromPreamble(Range);
4413 }
4414
4415 if (C.kind == CXCursor_TranslationUnit) {
4416 ASTUnit *TU = getCursorASTUnit(C);
4417 FileID MainID = TU->getSourceManager().getMainFileID();
4418 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4419 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4420 return SourceRange(Start, End);
4421 }
4422
4423 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004424 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004425 if (!D)
4426 return SourceRange();
4427
4428 SourceRange R = D->getSourceRange();
4429 // FIXME: Multiple variables declared in a single declaration
4430 // currently lack the information needed to correctly determine their
4431 // ranges when accounting for the type-specifier. We use context
4432 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4433 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004434 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004435 if (!cxcursor::isFirstInDeclGroup(C))
4436 R.setBegin(VD->getLocation());
4437 }
4438 return R;
4439 }
4440 return SourceRange();
4441}
4442
4443/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4444/// the decl-specifier-seq for declarations.
4445static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4446 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004447 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004448 if (!D)
4449 return SourceRange();
4450
4451 SourceRange R = D->getSourceRange();
4452
4453 // Adjust the start of the location for declarations preceded by
4454 // declaration specifiers.
4455 SourceLocation StartLoc;
4456 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4457 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4458 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004459 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004460 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4461 StartLoc = TI->getTypeLoc().getLocStart();
4462 }
4463
4464 if (StartLoc.isValid() && R.getBegin().isValid() &&
4465 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4466 R.setBegin(StartLoc);
4467
4468 // FIXME: Multiple variables declared in a single declaration
4469 // currently lack the information needed to correctly determine their
4470 // ranges when accounting for the type-specifier. We use context
4471 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4472 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004473 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004474 if (!cxcursor::isFirstInDeclGroup(C))
4475 R.setBegin(VD->getLocation());
4476 }
4477
4478 return R;
4479 }
4480
4481 return getRawCursorExtent(C);
4482}
4483
4484extern "C" {
4485
4486CXSourceRange clang_getCursorExtent(CXCursor C) {
4487 SourceRange R = getRawCursorExtent(C);
4488 if (R.isInvalid())
4489 return clang_getNullRange();
4490
4491 return cxloc::translateSourceRange(getCursorContext(C), R);
4492}
4493
4494CXCursor clang_getCursorReferenced(CXCursor C) {
4495 if (clang_isInvalid(C.kind))
4496 return clang_getNullCursor();
4497
4498 CXTranslationUnit tu = getCursorTU(C);
4499 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004500 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004501 if (!D)
4502 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004503 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004504 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004505 if (const ObjCPropertyImplDecl *PropImpl =
4506 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004507 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4508 return MakeCXCursor(Property, tu);
4509
4510 return C;
4511 }
4512
4513 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004514 const Expr *E = getCursorExpr(C);
4515 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004516 if (D) {
4517 CXCursor declCursor = MakeCXCursor(D, tu);
4518 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4519 declCursor);
4520 return declCursor;
4521 }
4522
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004523 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004524 return MakeCursorOverloadedDeclRef(Ovl, tu);
4525
4526 return clang_getNullCursor();
4527 }
4528
4529 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004530 const Stmt *S = getCursorStmt(C);
4531 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004532 if (LabelDecl *label = Goto->getLabel())
4533 if (LabelStmt *labelS = label->getStmt())
4534 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4535
4536 return clang_getNullCursor();
4537 }
4538
4539 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004540 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004541 return MakeMacroDefinitionCursor(Def, tu);
4542 }
4543
4544 if (!clang_isReference(C.kind))
4545 return clang_getNullCursor();
4546
4547 switch (C.kind) {
4548 case CXCursor_ObjCSuperClassRef:
4549 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4550
4551 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004552 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4553 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004554 return MakeCXCursor(Def, tu);
4555
4556 return MakeCXCursor(Prot, tu);
4557 }
4558
4559 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004560 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4561 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004562 return MakeCXCursor(Def, tu);
4563
4564 return MakeCXCursor(Class, tu);
4565 }
4566
4567 case CXCursor_TypeRef:
4568 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4569
4570 case CXCursor_TemplateRef:
4571 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4572
4573 case CXCursor_NamespaceRef:
4574 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4575
4576 case CXCursor_MemberRef:
4577 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4578
4579 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004580 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004581 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4582 tu ));
4583 }
4584
4585 case CXCursor_LabelRef:
4586 // FIXME: We end up faking the "parent" declaration here because we
4587 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004588 return MakeCXCursor(getCursorLabelRef(C).first,
4589 cxtu::getASTUnit(tu)->getASTContext()
4590 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 tu);
4592
4593 case CXCursor_OverloadedDeclRef:
4594 return C;
4595
4596 case CXCursor_VariableRef:
4597 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4598
4599 default:
4600 // We would prefer to enumerate all non-reference cursor kinds here.
4601 llvm_unreachable("Unhandled reference cursor kind");
4602 }
4603}
4604
4605CXCursor clang_getCursorDefinition(CXCursor C) {
4606 if (clang_isInvalid(C.kind))
4607 return clang_getNullCursor();
4608
4609 CXTranslationUnit TU = getCursorTU(C);
4610
4611 bool WasReference = false;
4612 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4613 C = clang_getCursorReferenced(C);
4614 WasReference = true;
4615 }
4616
4617 if (C.kind == CXCursor_MacroExpansion)
4618 return clang_getCursorReferenced(C);
4619
4620 if (!clang_isDeclaration(C.kind))
4621 return clang_getNullCursor();
4622
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004623 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004624 if (!D)
4625 return clang_getNullCursor();
4626
4627 switch (D->getKind()) {
4628 // Declaration kinds that don't really separate the notions of
4629 // declaration and definition.
4630 case Decl::Namespace:
4631 case Decl::Typedef:
4632 case Decl::TypeAlias:
4633 case Decl::TypeAliasTemplate:
4634 case Decl::TemplateTypeParm:
4635 case Decl::EnumConstant:
4636 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004637 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004638 case Decl::IndirectField:
4639 case Decl::ObjCIvar:
4640 case Decl::ObjCAtDefsField:
4641 case Decl::ImplicitParam:
4642 case Decl::ParmVar:
4643 case Decl::NonTypeTemplateParm:
4644 case Decl::TemplateTemplateParm:
4645 case Decl::ObjCCategoryImpl:
4646 case Decl::ObjCImplementation:
4647 case Decl::AccessSpec:
4648 case Decl::LinkageSpec:
4649 case Decl::ObjCPropertyImpl:
4650 case Decl::FileScopeAsm:
4651 case Decl::StaticAssert:
4652 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004653 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004654 case Decl::Label: // FIXME: Is this right??
4655 case Decl::ClassScopeFunctionSpecialization:
4656 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004657 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004658 return C;
4659
4660 // Declaration kinds that don't make any sense here, but are
4661 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004662 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 case Decl::TranslationUnit:
4664 break;
4665
4666 // Declaration kinds for which the definition is not resolvable.
4667 case Decl::UnresolvedUsingTypename:
4668 case Decl::UnresolvedUsingValue:
4669 break;
4670
4671 case Decl::UsingDirective:
4672 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4673 TU);
4674
4675 case Decl::NamespaceAlias:
4676 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4677
4678 case Decl::Enum:
4679 case Decl::Record:
4680 case Decl::CXXRecord:
4681 case Decl::ClassTemplateSpecialization:
4682 case Decl::ClassTemplatePartialSpecialization:
4683 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4684 return MakeCXCursor(Def, TU);
4685 return clang_getNullCursor();
4686
4687 case Decl::Function:
4688 case Decl::CXXMethod:
4689 case Decl::CXXConstructor:
4690 case Decl::CXXDestructor:
4691 case Decl::CXXConversion: {
4692 const FunctionDecl *Def = 0;
4693 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004694 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004695 return clang_getNullCursor();
4696 }
4697
Larisse Voufo39a1e502013-08-06 01:03:05 +00004698 case Decl::Var:
4699 case Decl::VarTemplateSpecialization:
4700 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004701 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004702 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004703 return MakeCXCursor(Def, TU);
4704 return clang_getNullCursor();
4705 }
4706
4707 case Decl::FunctionTemplate: {
4708 const FunctionDecl *Def = 0;
4709 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4710 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4711 return clang_getNullCursor();
4712 }
4713
4714 case Decl::ClassTemplate: {
4715 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4716 ->getDefinition())
4717 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4718 TU);
4719 return clang_getNullCursor();
4720 }
4721
Larisse Voufo39a1e502013-08-06 01:03:05 +00004722 case Decl::VarTemplate: {
4723 if (VarDecl *Def =
4724 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4725 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4726 return clang_getNullCursor();
4727 }
4728
Guy Benyei11169dd2012-12-18 14:30:41 +00004729 case Decl::Using:
4730 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4731 D->getLocation(), TU);
4732
4733 case Decl::UsingShadow:
4734 return clang_getCursorDefinition(
4735 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4736 TU));
4737
4738 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004739 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004740 if (Method->isThisDeclarationADefinition())
4741 return C;
4742
4743 // Dig out the method definition in the associated
4744 // @implementation, if we have it.
4745 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004746 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004747 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4748 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4749 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4750 Method->isInstanceMethod()))
4751 if (Def->isThisDeclarationADefinition())
4752 return MakeCXCursor(Def, TU);
4753
4754 return clang_getNullCursor();
4755 }
4756
4757 case Decl::ObjCCategory:
4758 if (ObjCCategoryImplDecl *Impl
4759 = cast<ObjCCategoryDecl>(D)->getImplementation())
4760 return MakeCXCursor(Impl, TU);
4761 return clang_getNullCursor();
4762
4763 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004764 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004765 return MakeCXCursor(Def, TU);
4766 return clang_getNullCursor();
4767
4768 case Decl::ObjCInterface: {
4769 // There are two notions of a "definition" for an Objective-C
4770 // class: the interface and its implementation. When we resolved a
4771 // reference to an Objective-C class, produce the @interface as
4772 // the definition; when we were provided with the interface,
4773 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004774 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004775 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004776 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004777 return MakeCXCursor(Def, TU);
4778 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4779 return MakeCXCursor(Impl, TU);
4780 return clang_getNullCursor();
4781 }
4782
4783 case Decl::ObjCProperty:
4784 // FIXME: We don't really know where to find the
4785 // ObjCPropertyImplDecls that implement this property.
4786 return clang_getNullCursor();
4787
4788 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004789 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004790 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004791 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004792 return MakeCXCursor(Def, TU);
4793
4794 return clang_getNullCursor();
4795
4796 case Decl::Friend:
4797 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4798 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4799 return clang_getNullCursor();
4800
4801 case Decl::FriendTemplate:
4802 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4803 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4804 return clang_getNullCursor();
4805 }
4806
4807 return clang_getNullCursor();
4808}
4809
4810unsigned clang_isCursorDefinition(CXCursor C) {
4811 if (!clang_isDeclaration(C.kind))
4812 return 0;
4813
4814 return clang_getCursorDefinition(C) == C;
4815}
4816
4817CXCursor clang_getCanonicalCursor(CXCursor C) {
4818 if (!clang_isDeclaration(C.kind))
4819 return C;
4820
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004821 if (const Decl *D = getCursorDecl(C)) {
4822 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004823 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4824 return MakeCXCursor(CatD, getCursorTU(C));
4825
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004826 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4827 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004828 return MakeCXCursor(IFD, getCursorTU(C));
4829
4830 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4831 }
4832
4833 return C;
4834}
4835
4836int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4837 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4838}
4839
4840unsigned clang_getNumOverloadedDecls(CXCursor C) {
4841 if (C.kind != CXCursor_OverloadedDeclRef)
4842 return 0;
4843
4844 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004845 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004846 return E->getNumDecls();
4847
4848 if (OverloadedTemplateStorage *S
4849 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4850 return S->size();
4851
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004852 const Decl *D = Storage.get<const Decl *>();
4853 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004854 return Using->shadow_size();
4855
4856 return 0;
4857}
4858
4859CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4860 if (cursor.kind != CXCursor_OverloadedDeclRef)
4861 return clang_getNullCursor();
4862
4863 if (index >= clang_getNumOverloadedDecls(cursor))
4864 return clang_getNullCursor();
4865
4866 CXTranslationUnit TU = getCursorTU(cursor);
4867 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004868 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004869 return MakeCXCursor(E->decls_begin()[index], TU);
4870
4871 if (OverloadedTemplateStorage *S
4872 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4873 return MakeCXCursor(S->begin()[index], TU);
4874
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004875 const Decl *D = Storage.get<const Decl *>();
4876 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004877 // FIXME: This is, unfortunately, linear time.
4878 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4879 std::advance(Pos, index);
4880 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4881 }
4882
4883 return clang_getNullCursor();
4884}
4885
4886void clang_getDefinitionSpellingAndExtent(CXCursor C,
4887 const char **startBuf,
4888 const char **endBuf,
4889 unsigned *startLine,
4890 unsigned *startColumn,
4891 unsigned *endLine,
4892 unsigned *endColumn) {
4893 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004894 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004895 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4896
4897 SourceManager &SM = FD->getASTContext().getSourceManager();
4898 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4899 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4900 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4901 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4902 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4903 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4904}
4905
4906
4907CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4908 unsigned PieceIndex) {
4909 RefNamePieces Pieces;
4910
4911 switch (C.kind) {
4912 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004913 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004914 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4915 E->getQualifierLoc().getSourceRange());
4916 break;
4917
4918 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004919 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004920 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4921 E->getQualifierLoc().getSourceRange(),
4922 E->getOptionalExplicitTemplateArgs());
4923 break;
4924
4925 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004926 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004927 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004928 const Expr *Callee = OCE->getCallee();
4929 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004930 Callee = ICE->getSubExpr();
4931
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004932 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004933 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4934 DRE->getQualifierLoc().getSourceRange());
4935 }
4936 break;
4937
4938 default:
4939 break;
4940 }
4941
4942 if (Pieces.empty()) {
4943 if (PieceIndex == 0)
4944 return clang_getCursorExtent(C);
4945 } else if (PieceIndex < Pieces.size()) {
4946 SourceRange R = Pieces[PieceIndex];
4947 if (R.isValid())
4948 return cxloc::translateSourceRange(getCursorContext(C), R);
4949 }
4950
4951 return clang_getNullRange();
4952}
4953
4954void clang_enableStackTraces(void) {
4955 llvm::sys::PrintStackTraceOnErrorSignal();
4956}
4957
4958void clang_executeOnThread(void (*fn)(void*), void *user_data,
4959 unsigned stack_size) {
4960 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4961}
4962
4963} // end: extern "C"
4964
4965//===----------------------------------------------------------------------===//
4966// Token-based Operations.
4967//===----------------------------------------------------------------------===//
4968
4969/* CXToken layout:
4970 * int_data[0]: a CXTokenKind
4971 * int_data[1]: starting token location
4972 * int_data[2]: token length
4973 * int_data[3]: reserved
4974 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4975 * otherwise unused.
4976 */
4977extern "C" {
4978
4979CXTokenKind clang_getTokenKind(CXToken CXTok) {
4980 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4981}
4982
4983CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4984 switch (clang_getTokenKind(CXTok)) {
4985 case CXToken_Identifier:
4986 case CXToken_Keyword:
4987 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004988 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004989 ->getNameStart());
4990
4991 case CXToken_Literal: {
4992 // We have stashed the starting pointer in the ptr_data field. Use it.
4993 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004994 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004995 }
4996
4997 case CXToken_Punctuation:
4998 case CXToken_Comment:
4999 break;
5000 }
5001
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005002 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005003 LOG_BAD_TU(TU);
5004 return cxstring::createEmpty();
5005 }
5006
Guy Benyei11169dd2012-12-18 14:30:41 +00005007 // We have to find the starting buffer pointer the hard way, by
5008 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005009 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005010 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005011 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005012
5013 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5014 std::pair<FileID, unsigned> LocInfo
5015 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5016 bool Invalid = false;
5017 StringRef Buffer
5018 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5019 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005020 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005021
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005022 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005023}
5024
5025CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005026 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005027 LOG_BAD_TU(TU);
5028 return clang_getNullLocation();
5029 }
5030
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005031 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005032 if (!CXXUnit)
5033 return clang_getNullLocation();
5034
5035 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5036 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5037}
5038
5039CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005040 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005041 LOG_BAD_TU(TU);
5042 return clang_getNullRange();
5043 }
5044
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005045 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005046 if (!CXXUnit)
5047 return clang_getNullRange();
5048
5049 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5050 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5051}
5052
5053static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5054 SmallVectorImpl<CXToken> &CXTokens) {
5055 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5056 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005057 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005058 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005059 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005060
5061 // Cannot tokenize across files.
5062 if (BeginLocInfo.first != EndLocInfo.first)
5063 return;
5064
5065 // Create a lexer
5066 bool Invalid = false;
5067 StringRef Buffer
5068 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5069 if (Invalid)
5070 return;
5071
5072 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5073 CXXUnit->getASTContext().getLangOpts(),
5074 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5075 Lex.SetCommentRetentionState(true);
5076
5077 // Lex tokens until we hit the end of the range.
5078 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5079 Token Tok;
5080 bool previousWasAt = false;
5081 do {
5082 // Lex the next token
5083 Lex.LexFromRawLexer(Tok);
5084 if (Tok.is(tok::eof))
5085 break;
5086
5087 // Initialize the CXToken.
5088 CXToken CXTok;
5089
5090 // - Common fields
5091 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5092 CXTok.int_data[2] = Tok.getLength();
5093 CXTok.int_data[3] = 0;
5094
5095 // - Kind-specific fields
5096 if (Tok.isLiteral()) {
5097 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005098 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005099 } else if (Tok.is(tok::raw_identifier)) {
5100 // Lookup the identifier to determine whether we have a keyword.
5101 IdentifierInfo *II
5102 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5103
5104 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5105 CXTok.int_data[0] = CXToken_Keyword;
5106 }
5107 else {
5108 CXTok.int_data[0] = Tok.is(tok::identifier)
5109 ? CXToken_Identifier
5110 : CXToken_Keyword;
5111 }
5112 CXTok.ptr_data = II;
5113 } else if (Tok.is(tok::comment)) {
5114 CXTok.int_data[0] = CXToken_Comment;
5115 CXTok.ptr_data = 0;
5116 } else {
5117 CXTok.int_data[0] = CXToken_Punctuation;
5118 CXTok.ptr_data = 0;
5119 }
5120 CXTokens.push_back(CXTok);
5121 previousWasAt = Tok.is(tok::at);
5122 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5123}
5124
5125void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5126 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005127 LOG_FUNC_SECTION {
5128 *Log << TU << ' ' << Range;
5129 }
5130
Guy Benyei11169dd2012-12-18 14:30:41 +00005131 if (Tokens)
5132 *Tokens = 0;
5133 if (NumTokens)
5134 *NumTokens = 0;
5135
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005136 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005137 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005138 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005139 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005140
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005141 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005142 if (!CXXUnit || !Tokens || !NumTokens)
5143 return;
5144
5145 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5146
5147 SourceRange R = cxloc::translateCXSourceRange(Range);
5148 if (R.isInvalid())
5149 return;
5150
5151 SmallVector<CXToken, 32> CXTokens;
5152 getTokens(CXXUnit, R, CXTokens);
5153
5154 if (CXTokens.empty())
5155 return;
5156
5157 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5158 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5159 *NumTokens = CXTokens.size();
5160}
5161
5162void clang_disposeTokens(CXTranslationUnit TU,
5163 CXToken *Tokens, unsigned NumTokens) {
5164 free(Tokens);
5165}
5166
5167} // end: extern "C"
5168
5169//===----------------------------------------------------------------------===//
5170// Token annotation APIs.
5171//===----------------------------------------------------------------------===//
5172
Guy Benyei11169dd2012-12-18 14:30:41 +00005173static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5174 CXCursor parent,
5175 CXClientData client_data);
5176static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5177 CXClientData client_data);
5178
5179namespace {
5180class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005181 CXToken *Tokens;
5182 CXCursor *Cursors;
5183 unsigned NumTokens;
5184 unsigned TokIdx;
5185 unsigned PreprocessingTokIdx;
5186 CursorVisitor AnnotateVis;
5187 SourceManager &SrcMgr;
5188 bool HasContextSensitiveKeywords;
5189
5190 struct PostChildrenInfo {
5191 CXCursor Cursor;
5192 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005193 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005194 unsigned BeforeChildrenTokenIdx;
5195 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005196 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005197
5198 CXToken &getTok(unsigned Idx) {
5199 assert(Idx < NumTokens);
5200 return Tokens[Idx];
5201 }
5202 const CXToken &getTok(unsigned Idx) const {
5203 assert(Idx < NumTokens);
5204 return Tokens[Idx];
5205 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005206 bool MoreTokens() const { return TokIdx < NumTokens; }
5207 unsigned NextToken() const { return TokIdx; }
5208 void AdvanceToken() { ++TokIdx; }
5209 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005210 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005211 }
5212 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005213 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005214 }
5215 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005216 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005217 }
5218
5219 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005220 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005221 SourceRange);
5222
5223public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005224 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005225 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005226 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005227 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005228 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005229 AnnotateTokensVisitor, this,
5230 /*VisitPreprocessorLast=*/true,
5231 /*VisitIncludedEntities=*/false,
5232 RegionOfInterest,
5233 /*VisitDeclsOnly=*/false,
5234 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005235 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005236 HasContextSensitiveKeywords(false) { }
5237
5238 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5239 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5240 bool postVisitChildren(CXCursor cursor);
5241 void AnnotateTokens();
5242
5243 /// \brief Determine whether the annotator saw any cursors that have
5244 /// context-sensitive keywords.
5245 bool hasContextSensitiveKeywords() const {
5246 return HasContextSensitiveKeywords;
5247 }
5248
5249 ~AnnotateTokensWorker() {
5250 assert(PostChildrenInfos.empty());
5251 }
5252};
5253}
5254
5255void AnnotateTokensWorker::AnnotateTokens() {
5256 // Walk the AST within the region of interest, annotating tokens
5257 // along the way.
5258 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005259}
Guy Benyei11169dd2012-12-18 14:30:41 +00005260
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005261static inline void updateCursorAnnotation(CXCursor &Cursor,
5262 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005263 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005264 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005265 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005266}
5267
5268/// \brief It annotates and advances tokens with a cursor until the comparison
5269//// between the cursor location and the source range is the same as
5270/// \arg compResult.
5271///
5272/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5273/// Pass RangeOverlap to annotate tokens inside a range.
5274void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5275 RangeComparisonResult compResult,
5276 SourceRange range) {
5277 while (MoreTokens()) {
5278 const unsigned I = NextToken();
5279 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005280 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5281 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005282
5283 SourceLocation TokLoc = GetTokenLoc(I);
5284 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005285 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005286 AdvanceToken();
5287 continue;
5288 }
5289 break;
5290 }
5291}
5292
5293/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005294/// \returns true if it advanced beyond all macro tokens, false otherwise.
5295bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005296 CXCursor updateC,
5297 RangeComparisonResult compResult,
5298 SourceRange range) {
5299 assert(MoreTokens());
5300 assert(isFunctionMacroToken(NextToken()) &&
5301 "Should be called only for macro arg tokens");
5302
5303 // This works differently than annotateAndAdvanceTokens; because expanded
5304 // macro arguments can have arbitrary translation-unit source order, we do not
5305 // advance the token index one by one until a token fails the range test.
5306 // We only advance once past all of the macro arg tokens if all of them
5307 // pass the range test. If one of them fails we keep the token index pointing
5308 // at the start of the macro arg tokens so that the failing token will be
5309 // annotated by a subsequent annotation try.
5310
5311 bool atLeastOneCompFail = false;
5312
5313 unsigned I = NextToken();
5314 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5315 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5316 if (TokLoc.isFileID())
5317 continue; // not macro arg token, it's parens or comma.
5318 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5319 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5320 Cursors[I] = updateC;
5321 } else
5322 atLeastOneCompFail = true;
5323 }
5324
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005325 if (atLeastOneCompFail)
5326 return false;
5327
5328 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5329 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005330}
5331
5332enum CXChildVisitResult
5333AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005334 SourceRange cursorRange = getRawCursorExtent(cursor);
5335 if (cursorRange.isInvalid())
5336 return CXChildVisit_Recurse;
5337
5338 if (!HasContextSensitiveKeywords) {
5339 // Objective-C properties can have context-sensitive keywords.
5340 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005341 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005342 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5343 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5344 }
5345 // Objective-C methods can have context-sensitive keywords.
5346 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5347 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005348 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005349 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5350 if (Method->getObjCDeclQualifier())
5351 HasContextSensitiveKeywords = true;
5352 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005353 for (const auto *P : Method->params()) {
5354 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005355 HasContextSensitiveKeywords = true;
5356 break;
5357 }
5358 }
5359 }
5360 }
5361 }
5362 // C++ methods can have context-sensitive keywords.
5363 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005364 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005365 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5366 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5367 HasContextSensitiveKeywords = true;
5368 }
5369 }
5370 // C++ classes can have context-sensitive keywords.
5371 else if (cursor.kind == CXCursor_StructDecl ||
5372 cursor.kind == CXCursor_ClassDecl ||
5373 cursor.kind == CXCursor_ClassTemplate ||
5374 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005375 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005376 if (D->hasAttr<FinalAttr>())
5377 HasContextSensitiveKeywords = true;
5378 }
5379 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005380
5381 // Don't override a property annotation with its getter/setter method.
5382 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5383 parent.kind == CXCursor_ObjCPropertyDecl)
5384 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005385
5386 if (clang_isPreprocessing(cursor.kind)) {
5387 // Items in the preprocessing record are kept separate from items in
5388 // declarations, so we keep a separate token index.
5389 unsigned SavedTokIdx = TokIdx;
5390 TokIdx = PreprocessingTokIdx;
5391
5392 // Skip tokens up until we catch up to the beginning of the preprocessing
5393 // entry.
5394 while (MoreTokens()) {
5395 const unsigned I = NextToken();
5396 SourceLocation TokLoc = GetTokenLoc(I);
5397 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5398 case RangeBefore:
5399 AdvanceToken();
5400 continue;
5401 case RangeAfter:
5402 case RangeOverlap:
5403 break;
5404 }
5405 break;
5406 }
5407
5408 // Look at all of the tokens within this range.
5409 while (MoreTokens()) {
5410 const unsigned I = NextToken();
5411 SourceLocation TokLoc = GetTokenLoc(I);
5412 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5413 case RangeBefore:
5414 llvm_unreachable("Infeasible");
5415 case RangeAfter:
5416 break;
5417 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005418 // For macro expansions, just note where the beginning of the macro
5419 // expansion occurs.
5420 if (cursor.kind == CXCursor_MacroExpansion) {
5421 if (TokLoc == cursorRange.getBegin())
5422 Cursors[I] = cursor;
5423 AdvanceToken();
5424 break;
5425 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005426 // We may have already annotated macro names inside macro definitions.
5427 if (Cursors[I].kind != CXCursor_MacroExpansion)
5428 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005429 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005430 continue;
5431 }
5432 break;
5433 }
5434
5435 // Save the preprocessing token index; restore the non-preprocessing
5436 // token index.
5437 PreprocessingTokIdx = TokIdx;
5438 TokIdx = SavedTokIdx;
5439 return CXChildVisit_Recurse;
5440 }
5441
5442 if (cursorRange.isInvalid())
5443 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005444
5445 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005446 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005447 const enum CXCursorKind K = clang_getCursorKind(parent);
5448 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005449 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5450 // Attributes are annotated out-of-order, skip tokens until we reach it.
5451 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005452 ? clang_getNullCursor() : parent;
5453
5454 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5455
5456 // Avoid having the cursor of an expression "overwrite" the annotation of the
5457 // variable declaration that it belongs to.
5458 // This can happen for C++ constructor expressions whose range generally
5459 // include the variable declaration, e.g.:
5460 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005461 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005462 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005463 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005464 const unsigned I = NextToken();
5465 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5466 E->getLocStart() == D->getLocation() &&
5467 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005468 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005469 AdvanceToken();
5470 }
5471 }
5472 }
5473
5474 // Before recursing into the children keep some state that we are going
5475 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5476 // extra work after the child nodes are visited.
5477 // Note that we don't call VisitChildren here to avoid traversing statements
5478 // code-recursively which can blow the stack.
5479
5480 PostChildrenInfo Info;
5481 Info.Cursor = cursor;
5482 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005483 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005484 Info.BeforeChildrenTokenIdx = NextToken();
5485 PostChildrenInfos.push_back(Info);
5486
5487 return CXChildVisit_Recurse;
5488}
5489
5490bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5491 if (PostChildrenInfos.empty())
5492 return false;
5493 const PostChildrenInfo &Info = PostChildrenInfos.back();
5494 if (!clang_equalCursors(Info.Cursor, cursor))
5495 return false;
5496
5497 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5498 const unsigned AfterChildren = NextToken();
5499 SourceRange cursorRange = Info.CursorRange;
5500
5501 // Scan the tokens that are at the end of the cursor, but are not captured
5502 // but the child cursors.
5503 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5504
5505 // Scan the tokens that are at the beginning of the cursor, but are not
5506 // capture by the child cursors.
5507 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5508 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5509 break;
5510
5511 Cursors[I] = cursor;
5512 }
5513
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005514 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5515 // encountered the attribute cursor.
5516 if (clang_isAttribute(cursor.kind))
5517 TokIdx = Info.BeforeReachingCursorIdx;
5518
Guy Benyei11169dd2012-12-18 14:30:41 +00005519 PostChildrenInfos.pop_back();
5520 return false;
5521}
5522
5523static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5524 CXCursor parent,
5525 CXClientData client_data) {
5526 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5527}
5528
5529static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5530 CXClientData client_data) {
5531 return static_cast<AnnotateTokensWorker*>(client_data)->
5532 postVisitChildren(cursor);
5533}
5534
5535namespace {
5536
5537/// \brief Uses the macro expansions in the preprocessing record to find
5538/// and mark tokens that are macro arguments. This info is used by the
5539/// AnnotateTokensWorker.
5540class MarkMacroArgTokensVisitor {
5541 SourceManager &SM;
5542 CXToken *Tokens;
5543 unsigned NumTokens;
5544 unsigned CurIdx;
5545
5546public:
5547 MarkMacroArgTokensVisitor(SourceManager &SM,
5548 CXToken *tokens, unsigned numTokens)
5549 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5550
5551 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5552 if (cursor.kind != CXCursor_MacroExpansion)
5553 return CXChildVisit_Continue;
5554
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005555 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005556 if (macroRange.getBegin() == macroRange.getEnd())
5557 return CXChildVisit_Continue; // it's not a function macro.
5558
5559 for (; CurIdx < NumTokens; ++CurIdx) {
5560 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5561 macroRange.getBegin()))
5562 break;
5563 }
5564
5565 if (CurIdx == NumTokens)
5566 return CXChildVisit_Break;
5567
5568 for (; CurIdx < NumTokens; ++CurIdx) {
5569 SourceLocation tokLoc = getTokenLoc(CurIdx);
5570 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5571 break;
5572
5573 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5574 }
5575
5576 if (CurIdx == NumTokens)
5577 return CXChildVisit_Break;
5578
5579 return CXChildVisit_Continue;
5580 }
5581
5582private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005583 CXToken &getTok(unsigned Idx) {
5584 assert(Idx < NumTokens);
5585 return Tokens[Idx];
5586 }
5587 const CXToken &getTok(unsigned Idx) const {
5588 assert(Idx < NumTokens);
5589 return Tokens[Idx];
5590 }
5591
Guy Benyei11169dd2012-12-18 14:30:41 +00005592 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005593 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005594 }
5595
5596 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5597 // The third field is reserved and currently not used. Use it here
5598 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005599 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005600 }
5601};
5602
5603} // end anonymous namespace
5604
5605static CXChildVisitResult
5606MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5607 CXClientData client_data) {
5608 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5609 parent);
5610}
5611
5612namespace {
5613 struct clang_annotateTokens_Data {
5614 CXTranslationUnit TU;
5615 ASTUnit *CXXUnit;
5616 CXToken *Tokens;
5617 unsigned NumTokens;
5618 CXCursor *Cursors;
5619 };
5620}
5621
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005622/// \brief Used by \c annotatePreprocessorTokens.
5623/// \returns true if lexing was finished, false otherwise.
5624static bool lexNext(Lexer &Lex, Token &Tok,
5625 unsigned &NextIdx, unsigned NumTokens) {
5626 if (NextIdx >= NumTokens)
5627 return true;
5628
5629 ++NextIdx;
5630 Lex.LexFromRawLexer(Tok);
5631 if (Tok.is(tok::eof))
5632 return true;
5633
5634 return false;
5635}
5636
Guy Benyei11169dd2012-12-18 14:30:41 +00005637static void annotatePreprocessorTokens(CXTranslationUnit TU,
5638 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005639 CXCursor *Cursors,
5640 CXToken *Tokens,
5641 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005642 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005643
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005644 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005645 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5646 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005647 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005648 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005649 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005650
5651 if (BeginLocInfo.first != EndLocInfo.first)
5652 return;
5653
5654 StringRef Buffer;
5655 bool Invalid = false;
5656 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5657 if (Buffer.empty() || Invalid)
5658 return;
5659
5660 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5661 CXXUnit->getASTContext().getLangOpts(),
5662 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5663 Buffer.end());
5664 Lex.SetCommentRetentionState(true);
5665
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005666 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005667 // Lex tokens in raw mode until we hit the end of the range, to avoid
5668 // entering #includes or expanding macros.
5669 while (true) {
5670 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005671 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5672 break;
5673 unsigned TokIdx = NextIdx-1;
5674 assert(Tok.getLocation() ==
5675 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005676
5677 reprocess:
5678 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005679 // We have found a preprocessing directive. Annotate the tokens
5680 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005681 //
5682 // FIXME: Some simple tests here could identify macro definitions and
5683 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005684
5685 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005686 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5687 break;
5688
5689 MacroInfo *MI = 0;
5690 if (Tok.is(tok::raw_identifier) &&
5691 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5692 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5693 break;
5694
5695 if (Tok.is(tok::raw_identifier)) {
5696 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5697 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5698 SourceLocation MappedTokLoc =
5699 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5700 MI = getMacroInfo(II, MappedTokLoc, TU);
5701 }
5702 }
5703
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005704 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005705 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005706 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5707 finished = true;
5708 break;
5709 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005710 // If we are in a macro definition, check if the token was ever a
5711 // macro name and annotate it if that's the case.
5712 if (MI) {
5713 SourceLocation SaveLoc = Tok.getLocation();
5714 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5715 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5716 Tok.setLocation(SaveLoc);
5717 if (MacroDef)
5718 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5719 Tok.getLocation(), TU);
5720 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005721 } while (!Tok.isAtStartOfLine());
5722
5723 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5724 assert(TokIdx <= LastIdx);
5725 SourceLocation EndLoc =
5726 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5727 CXCursor Cursor =
5728 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5729
5730 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005731 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005732
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005733 if (finished)
5734 break;
5735 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005736 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005737 }
5738}
5739
5740// This gets run a separate thread to avoid stack blowout.
5741static void clang_annotateTokensImpl(void *UserData) {
5742 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5743 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5744 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5745 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5746 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5747
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005748 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005749 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5750 setThreadBackgroundPriority();
5751
5752 // Determine the region of interest, which contains all of the tokens.
5753 SourceRange RegionOfInterest;
5754 RegionOfInterest.setBegin(
5755 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5756 RegionOfInterest.setEnd(
5757 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5758 Tokens[NumTokens-1])));
5759
Guy Benyei11169dd2012-12-18 14:30:41 +00005760 // Relex the tokens within the source range to look for preprocessing
5761 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005762 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005763
5764 // If begin location points inside a macro argument, set it to the expansion
5765 // location so we can have the full context when annotating semantically.
5766 {
5767 SourceManager &SM = CXXUnit->getSourceManager();
5768 SourceLocation Loc =
5769 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5770 if (Loc.isMacroID())
5771 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5772 }
5773
Guy Benyei11169dd2012-12-18 14:30:41 +00005774 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5775 // Search and mark tokens that are macro argument expansions.
5776 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5777 Tokens, NumTokens);
5778 CursorVisitor MacroArgMarker(TU,
5779 MarkMacroArgTokensVisitorDelegate, &Visitor,
5780 /*VisitPreprocessorLast=*/true,
5781 /*VisitIncludedEntities=*/false,
5782 RegionOfInterest);
5783 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5784 }
5785
5786 // Annotate all of the source locations in the region of interest that map to
5787 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005788 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005789
5790 // FIXME: We use a ridiculous stack size here because the data-recursion
5791 // algorithm uses a large stack frame than the non-data recursive version,
5792 // and AnnotationTokensWorker currently transforms the data-recursion
5793 // algorithm back into a traditional recursion by explicitly calling
5794 // VisitChildren(). We will need to remove this explicit recursive call.
5795 W.AnnotateTokens();
5796
5797 // If we ran into any entities that involve context-sensitive keywords,
5798 // take another pass through the tokens to mark them as such.
5799 if (W.hasContextSensitiveKeywords()) {
5800 for (unsigned I = 0; I != NumTokens; ++I) {
5801 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5802 continue;
5803
5804 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5805 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005806 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005807 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5808 if (Property->getPropertyAttributesAsWritten() != 0 &&
5809 llvm::StringSwitch<bool>(II->getName())
5810 .Case("readonly", true)
5811 .Case("assign", true)
5812 .Case("unsafe_unretained", true)
5813 .Case("readwrite", true)
5814 .Case("retain", true)
5815 .Case("copy", true)
5816 .Case("nonatomic", true)
5817 .Case("atomic", true)
5818 .Case("getter", true)
5819 .Case("setter", true)
5820 .Case("strong", true)
5821 .Case("weak", true)
5822 .Default(false))
5823 Tokens[I].int_data[0] = CXToken_Keyword;
5824 }
5825 continue;
5826 }
5827
5828 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5829 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5830 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5831 if (llvm::StringSwitch<bool>(II->getName())
5832 .Case("in", true)
5833 .Case("out", true)
5834 .Case("inout", true)
5835 .Case("oneway", true)
5836 .Case("bycopy", true)
5837 .Case("byref", true)
5838 .Default(false))
5839 Tokens[I].int_data[0] = CXToken_Keyword;
5840 continue;
5841 }
5842
5843 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5844 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5845 Tokens[I].int_data[0] = CXToken_Keyword;
5846 continue;
5847 }
5848 }
5849 }
5850}
5851
5852extern "C" {
5853
5854void clang_annotateTokens(CXTranslationUnit TU,
5855 CXToken *Tokens, unsigned NumTokens,
5856 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005857 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005858 LOG_BAD_TU(TU);
5859 return;
5860 }
5861 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005862 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005863 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005864 }
5865
5866 LOG_FUNC_SECTION {
5867 *Log << TU << ' ';
5868 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5869 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5870 *Log << clang_getRange(bloc, eloc);
5871 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005872
5873 // Any token we don't specifically annotate will have a NULL cursor.
5874 CXCursor C = clang_getNullCursor();
5875 for (unsigned I = 0; I != NumTokens; ++I)
5876 Cursors[I] = C;
5877
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005878 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005879 if (!CXXUnit)
5880 return;
5881
5882 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5883
5884 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5885 llvm::CrashRecoveryContext CRC;
5886 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5887 GetSafetyThreadStackSize() * 2)) {
5888 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5889 }
5890}
5891
5892} // end: extern "C"
5893
5894//===----------------------------------------------------------------------===//
5895// Operations for querying linkage of a cursor.
5896//===----------------------------------------------------------------------===//
5897
5898extern "C" {
5899CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5900 if (!clang_isDeclaration(cursor.kind))
5901 return CXLinkage_Invalid;
5902
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005903 const Decl *D = cxcursor::getCursorDecl(cursor);
5904 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005905 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005906 case NoLinkage:
5907 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005908 case InternalLinkage: return CXLinkage_Internal;
5909 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5910 case ExternalLinkage: return CXLinkage_External;
5911 };
5912
5913 return CXLinkage_Invalid;
5914}
5915} // end: extern "C"
5916
5917//===----------------------------------------------------------------------===//
5918// Operations for querying language of a cursor.
5919//===----------------------------------------------------------------------===//
5920
5921static CXLanguageKind getDeclLanguage(const Decl *D) {
5922 if (!D)
5923 return CXLanguage_C;
5924
5925 switch (D->getKind()) {
5926 default:
5927 break;
5928 case Decl::ImplicitParam:
5929 case Decl::ObjCAtDefsField:
5930 case Decl::ObjCCategory:
5931 case Decl::ObjCCategoryImpl:
5932 case Decl::ObjCCompatibleAlias:
5933 case Decl::ObjCImplementation:
5934 case Decl::ObjCInterface:
5935 case Decl::ObjCIvar:
5936 case Decl::ObjCMethod:
5937 case Decl::ObjCProperty:
5938 case Decl::ObjCPropertyImpl:
5939 case Decl::ObjCProtocol:
5940 return CXLanguage_ObjC;
5941 case Decl::CXXConstructor:
5942 case Decl::CXXConversion:
5943 case Decl::CXXDestructor:
5944 case Decl::CXXMethod:
5945 case Decl::CXXRecord:
5946 case Decl::ClassTemplate:
5947 case Decl::ClassTemplatePartialSpecialization:
5948 case Decl::ClassTemplateSpecialization:
5949 case Decl::Friend:
5950 case Decl::FriendTemplate:
5951 case Decl::FunctionTemplate:
5952 case Decl::LinkageSpec:
5953 case Decl::Namespace:
5954 case Decl::NamespaceAlias:
5955 case Decl::NonTypeTemplateParm:
5956 case Decl::StaticAssert:
5957 case Decl::TemplateTemplateParm:
5958 case Decl::TemplateTypeParm:
5959 case Decl::UnresolvedUsingTypename:
5960 case Decl::UnresolvedUsingValue:
5961 case Decl::Using:
5962 case Decl::UsingDirective:
5963 case Decl::UsingShadow:
5964 return CXLanguage_CPlusPlus;
5965 }
5966
5967 return CXLanguage_C;
5968}
5969
5970extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005971
5972static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5973 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5974 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005975
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005976 switch (D->getAvailability()) {
5977 case AR_Available:
5978 case AR_NotYetIntroduced:
5979 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005980 return getCursorAvailabilityForDecl(
5981 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005982 return CXAvailability_Available;
5983
5984 case AR_Deprecated:
5985 return CXAvailability_Deprecated;
5986
5987 case AR_Unavailable:
5988 return CXAvailability_NotAvailable;
5989 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005990
5991 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005992}
5993
Guy Benyei11169dd2012-12-18 14:30:41 +00005994enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5995 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005996 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5997 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005998
5999 return CXAvailability_Available;
6000}
6001
6002static CXVersion convertVersion(VersionTuple In) {
6003 CXVersion Out = { -1, -1, -1 };
6004 if (In.empty())
6005 return Out;
6006
6007 Out.Major = In.getMajor();
6008
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006009 Optional<unsigned> Minor = In.getMinor();
6010 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006011 Out.Minor = *Minor;
6012 else
6013 return Out;
6014
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006015 Optional<unsigned> Subminor = In.getSubminor();
6016 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006017 Out.Subminor = *Subminor;
6018
6019 return Out;
6020}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006021
6022static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6023 int *always_deprecated,
6024 CXString *deprecated_message,
6025 int *always_unavailable,
6026 CXString *unavailable_message,
6027 CXPlatformAvailability *availability,
6028 int availability_size) {
6029 bool HadAvailAttr = false;
6030 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006031 for (auto A : D->attrs()) {
6032 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006033 HadAvailAttr = true;
6034 if (always_deprecated)
6035 *always_deprecated = 1;
6036 if (deprecated_message)
6037 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
6038 continue;
6039 }
6040
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006041 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006042 HadAvailAttr = true;
6043 if (always_unavailable)
6044 *always_unavailable = 1;
6045 if (unavailable_message) {
6046 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6047 }
6048 continue;
6049 }
6050
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006051 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006052 HadAvailAttr = true;
6053 if (N < availability_size) {
6054 availability[N].Platform
6055 = cxstring::createDup(Avail->getPlatform()->getName());
6056 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6057 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6058 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6059 availability[N].Unavailable = Avail->getUnavailable();
6060 availability[N].Message = cxstring::createDup(Avail->getMessage());
6061 }
6062 ++N;
6063 }
6064 }
6065
6066 if (!HadAvailAttr)
6067 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6068 return getCursorPlatformAvailabilityForDecl(
6069 cast<Decl>(EnumConst->getDeclContext()),
6070 always_deprecated,
6071 deprecated_message,
6072 always_unavailable,
6073 unavailable_message,
6074 availability,
6075 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006076
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006077 return N;
6078}
6079
Guy Benyei11169dd2012-12-18 14:30:41 +00006080int clang_getCursorPlatformAvailability(CXCursor cursor,
6081 int *always_deprecated,
6082 CXString *deprecated_message,
6083 int *always_unavailable,
6084 CXString *unavailable_message,
6085 CXPlatformAvailability *availability,
6086 int availability_size) {
6087 if (always_deprecated)
6088 *always_deprecated = 0;
6089 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006090 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006091 if (always_unavailable)
6092 *always_unavailable = 0;
6093 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006094 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006095
Guy Benyei11169dd2012-12-18 14:30:41 +00006096 if (!clang_isDeclaration(cursor.kind))
6097 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006098
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006099 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006100 if (!D)
6101 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006102
6103 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6104 deprecated_message,
6105 always_unavailable,
6106 unavailable_message,
6107 availability,
6108 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006109}
6110
6111void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6112 clang_disposeString(availability->Platform);
6113 clang_disposeString(availability->Message);
6114}
6115
6116CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6117 if (clang_isDeclaration(cursor.kind))
6118 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6119
6120 return CXLanguage_Invalid;
6121}
6122
6123 /// \brief If the given cursor is the "templated" declaration
6124 /// descibing a class or function template, return the class or
6125 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006126static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006127 if (!D)
6128 return 0;
6129
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006130 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006131 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6132 return FunTmpl;
6133
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006134 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006135 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6136 return ClassTmpl;
6137
6138 return D;
6139}
6140
6141CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6142 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006143 if (const Decl *D = getCursorDecl(cursor)) {
6144 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006145 if (!DC)
6146 return clang_getNullCursor();
6147
6148 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6149 getCursorTU(cursor));
6150 }
6151 }
6152
6153 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006154 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006155 return MakeCXCursor(D, getCursorTU(cursor));
6156 }
6157
6158 return clang_getNullCursor();
6159}
6160
6161CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6162 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006163 if (const Decl *D = getCursorDecl(cursor)) {
6164 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006165 if (!DC)
6166 return clang_getNullCursor();
6167
6168 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6169 getCursorTU(cursor));
6170 }
6171 }
6172
6173 // FIXME: Note that we can't easily compute the lexical context of a
6174 // statement or expression, so we return nothing.
6175 return clang_getNullCursor();
6176}
6177
6178CXFile clang_getIncludedFile(CXCursor cursor) {
6179 if (cursor.kind != CXCursor_InclusionDirective)
6180 return 0;
6181
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006182 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006183 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006184}
6185
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006186unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6187 if (C.kind != CXCursor_ObjCPropertyDecl)
6188 return CXObjCPropertyAttr_noattr;
6189
6190 unsigned Result = CXObjCPropertyAttr_noattr;
6191 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6192 ObjCPropertyDecl::PropertyAttributeKind Attr =
6193 PD->getPropertyAttributesAsWritten();
6194
6195#define SET_CXOBJCPROP_ATTR(A) \
6196 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6197 Result |= CXObjCPropertyAttr_##A
6198 SET_CXOBJCPROP_ATTR(readonly);
6199 SET_CXOBJCPROP_ATTR(getter);
6200 SET_CXOBJCPROP_ATTR(assign);
6201 SET_CXOBJCPROP_ATTR(readwrite);
6202 SET_CXOBJCPROP_ATTR(retain);
6203 SET_CXOBJCPROP_ATTR(copy);
6204 SET_CXOBJCPROP_ATTR(nonatomic);
6205 SET_CXOBJCPROP_ATTR(setter);
6206 SET_CXOBJCPROP_ATTR(atomic);
6207 SET_CXOBJCPROP_ATTR(weak);
6208 SET_CXOBJCPROP_ATTR(strong);
6209 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6210#undef SET_CXOBJCPROP_ATTR
6211
6212 return Result;
6213}
6214
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006215unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6216 if (!clang_isDeclaration(C.kind))
6217 return CXObjCDeclQualifier_None;
6218
6219 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6220 const Decl *D = getCursorDecl(C);
6221 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6222 QT = MD->getObjCDeclQualifier();
6223 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6224 QT = PD->getObjCDeclQualifier();
6225 if (QT == Decl::OBJC_TQ_None)
6226 return CXObjCDeclQualifier_None;
6227
6228 unsigned Result = CXObjCDeclQualifier_None;
6229 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6230 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6231 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6232 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6233 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6234 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6235
6236 return Result;
6237}
6238
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006239unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6240 if (!clang_isDeclaration(C.kind))
6241 return 0;
6242
6243 const Decl *D = getCursorDecl(C);
6244 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6245 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6246 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6247 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6248
6249 return 0;
6250}
6251
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006252unsigned clang_Cursor_isVariadic(CXCursor C) {
6253 if (!clang_isDeclaration(C.kind))
6254 return 0;
6255
6256 const Decl *D = getCursorDecl(C);
6257 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6258 return FD->isVariadic();
6259 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6260 return MD->isVariadic();
6261
6262 return 0;
6263}
6264
Guy Benyei11169dd2012-12-18 14:30:41 +00006265CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6266 if (!clang_isDeclaration(C.kind))
6267 return clang_getNullRange();
6268
6269 const Decl *D = getCursorDecl(C);
6270 ASTContext &Context = getCursorContext(C);
6271 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6272 if (!RC)
6273 return clang_getNullRange();
6274
6275 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6276}
6277
6278CXString clang_Cursor_getRawCommentText(CXCursor C) {
6279 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006280 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006281
6282 const Decl *D = getCursorDecl(C);
6283 ASTContext &Context = getCursorContext(C);
6284 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6285 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6286 StringRef();
6287
6288 // Don't duplicate the string because RawText points directly into source
6289 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006290 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006291}
6292
6293CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6294 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006295 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006296
6297 const Decl *D = getCursorDecl(C);
6298 const ASTContext &Context = getCursorContext(C);
6299 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6300
6301 if (RC) {
6302 StringRef BriefText = RC->getBriefText(Context);
6303
6304 // Don't duplicate the string because RawComment ensures that this memory
6305 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006306 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006307 }
6308
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006309 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006310}
6311
6312CXComment clang_Cursor_getParsedComment(CXCursor C) {
6313 if (!clang_isDeclaration(C.kind))
6314 return cxcomment::createCXComment(NULL, NULL);
6315
6316 const Decl *D = getCursorDecl(C);
6317 const ASTContext &Context = getCursorContext(C);
6318 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6319
6320 return cxcomment::createCXComment(FC, getCursorTU(C));
6321}
6322
6323CXModule clang_Cursor_getModule(CXCursor C) {
6324 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006325 if (const ImportDecl *ImportD =
6326 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006327 return ImportD->getImportedModule();
6328 }
6329
6330 return 0;
6331}
6332
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006333CXFile clang_Module_getASTFile(CXModule CXMod) {
6334 if (!CXMod)
6335 return 0;
6336 Module *Mod = static_cast<Module*>(CXMod);
6337 return const_cast<FileEntry *>(Mod->getASTFile());
6338}
6339
Guy Benyei11169dd2012-12-18 14:30:41 +00006340CXModule clang_Module_getParent(CXModule CXMod) {
6341 if (!CXMod)
6342 return 0;
6343 Module *Mod = static_cast<Module*>(CXMod);
6344 return Mod->Parent;
6345}
6346
6347CXString clang_Module_getName(CXModule CXMod) {
6348 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006349 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006350 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006351 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006352}
6353
6354CXString clang_Module_getFullName(CXModule CXMod) {
6355 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006356 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006357 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006358 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006359}
6360
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006361unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6362 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006363 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006364 LOG_BAD_TU(TU);
6365 return 0;
6366 }
6367 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006368 return 0;
6369 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006370 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6371 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6372 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006373}
6374
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006375CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6376 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006377 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006378 LOG_BAD_TU(TU);
6379 return 0;
6380 }
6381 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006382 return 0;
6383 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006384 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006385
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006386 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6387 if (Index < TopHeaders.size())
6388 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006389
6390 return 0;
6391}
6392
6393} // end: extern "C"
6394
6395//===----------------------------------------------------------------------===//
6396// C++ AST instrospection.
6397//===----------------------------------------------------------------------===//
6398
6399extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006400unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6401 if (!clang_isDeclaration(C.kind))
6402 return 0;
6403
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006404 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006405 const CXXMethodDecl *Method =
6406 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006407 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6408}
6409
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006410unsigned clang_CXXMethod_isConst(CXCursor C) {
6411 if (!clang_isDeclaration(C.kind))
6412 return 0;
6413
6414 const Decl *D = cxcursor::getCursorDecl(C);
6415 const CXXMethodDecl *Method =
6416 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
6417 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6418}
6419
Guy Benyei11169dd2012-12-18 14:30:41 +00006420unsigned clang_CXXMethod_isStatic(CXCursor C) {
6421 if (!clang_isDeclaration(C.kind))
6422 return 0;
6423
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006424 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006425 const CXXMethodDecl *Method =
6426 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006427 return (Method && Method->isStatic()) ? 1 : 0;
6428}
6429
6430unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6431 if (!clang_isDeclaration(C.kind))
6432 return 0;
6433
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006434 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006435 const CXXMethodDecl *Method =
6436 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006437 return (Method && Method->isVirtual()) ? 1 : 0;
6438}
6439} // end: extern "C"
6440
6441//===----------------------------------------------------------------------===//
6442// Attribute introspection.
6443//===----------------------------------------------------------------------===//
6444
6445extern "C" {
6446CXType clang_getIBOutletCollectionType(CXCursor C) {
6447 if (C.kind != CXCursor_IBOutletCollectionAttr)
6448 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6449
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006450 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006451 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6452
6453 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6454}
6455} // end: extern "C"
6456
6457//===----------------------------------------------------------------------===//
6458// Inspecting memory usage.
6459//===----------------------------------------------------------------------===//
6460
6461typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6462
6463static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6464 enum CXTUResourceUsageKind k,
6465 unsigned long amount) {
6466 CXTUResourceUsageEntry entry = { k, amount };
6467 entries.push_back(entry);
6468}
6469
6470extern "C" {
6471
6472const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6473 const char *str = "";
6474 switch (kind) {
6475 case CXTUResourceUsage_AST:
6476 str = "ASTContext: expressions, declarations, and types";
6477 break;
6478 case CXTUResourceUsage_Identifiers:
6479 str = "ASTContext: identifiers";
6480 break;
6481 case CXTUResourceUsage_Selectors:
6482 str = "ASTContext: selectors";
6483 break;
6484 case CXTUResourceUsage_GlobalCompletionResults:
6485 str = "Code completion: cached global results";
6486 break;
6487 case CXTUResourceUsage_SourceManagerContentCache:
6488 str = "SourceManager: content cache allocator";
6489 break;
6490 case CXTUResourceUsage_AST_SideTables:
6491 str = "ASTContext: side tables";
6492 break;
6493 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6494 str = "SourceManager: malloc'ed memory buffers";
6495 break;
6496 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6497 str = "SourceManager: mmap'ed memory buffers";
6498 break;
6499 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6500 str = "ExternalASTSource: malloc'ed memory buffers";
6501 break;
6502 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6503 str = "ExternalASTSource: mmap'ed memory buffers";
6504 break;
6505 case CXTUResourceUsage_Preprocessor:
6506 str = "Preprocessor: malloc'ed memory";
6507 break;
6508 case CXTUResourceUsage_PreprocessingRecord:
6509 str = "Preprocessor: PreprocessingRecord";
6510 break;
6511 case CXTUResourceUsage_SourceManager_DataStructures:
6512 str = "SourceManager: data structures and tables";
6513 break;
6514 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6515 str = "Preprocessor: header search tables";
6516 break;
6517 }
6518 return str;
6519}
6520
6521CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006522 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006523 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006524 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6525 return usage;
6526 }
6527
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006528 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006529 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006530 ASTContext &astContext = astUnit->getASTContext();
6531
6532 // How much memory is used by AST nodes and types?
6533 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6534 (unsigned long) astContext.getASTAllocatedMemory());
6535
6536 // How much memory is used by identifiers?
6537 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6538 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6539
6540 // How much memory is used for selectors?
6541 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6542 (unsigned long) astContext.Selectors.getTotalMemory());
6543
6544 // How much memory is used by ASTContext's side tables?
6545 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6546 (unsigned long) astContext.getSideTableAllocatedMemory());
6547
6548 // How much memory is used for caching global code completion results?
6549 unsigned long completionBytes = 0;
6550 if (GlobalCodeCompletionAllocator *completionAllocator =
6551 astUnit->getCachedCompletionAllocator().getPtr()) {
6552 completionBytes = completionAllocator->getTotalMemory();
6553 }
6554 createCXTUResourceUsageEntry(*entries,
6555 CXTUResourceUsage_GlobalCompletionResults,
6556 completionBytes);
6557
6558 // How much memory is being used by SourceManager's content cache?
6559 createCXTUResourceUsageEntry(*entries,
6560 CXTUResourceUsage_SourceManagerContentCache,
6561 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6562
6563 // How much memory is being used by the MemoryBuffer's in SourceManager?
6564 const SourceManager::MemoryBufferSizes &srcBufs =
6565 astUnit->getSourceManager().getMemoryBufferSizes();
6566
6567 createCXTUResourceUsageEntry(*entries,
6568 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6569 (unsigned long) srcBufs.malloc_bytes);
6570 createCXTUResourceUsageEntry(*entries,
6571 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6572 (unsigned long) srcBufs.mmap_bytes);
6573 createCXTUResourceUsageEntry(*entries,
6574 CXTUResourceUsage_SourceManager_DataStructures,
6575 (unsigned long) astContext.getSourceManager()
6576 .getDataStructureSizes());
6577
6578 // How much memory is being used by the ExternalASTSource?
6579 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6580 const ExternalASTSource::MemoryBufferSizes &sizes =
6581 esrc->getMemoryBufferSizes();
6582
6583 createCXTUResourceUsageEntry(*entries,
6584 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6585 (unsigned long) sizes.malloc_bytes);
6586 createCXTUResourceUsageEntry(*entries,
6587 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6588 (unsigned long) sizes.mmap_bytes);
6589 }
6590
6591 // How much memory is being used by the Preprocessor?
6592 Preprocessor &pp = astUnit->getPreprocessor();
6593 createCXTUResourceUsageEntry(*entries,
6594 CXTUResourceUsage_Preprocessor,
6595 pp.getTotalMemory());
6596
6597 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6598 createCXTUResourceUsageEntry(*entries,
6599 CXTUResourceUsage_PreprocessingRecord,
6600 pRec->getTotalMemory());
6601 }
6602
6603 createCXTUResourceUsageEntry(*entries,
6604 CXTUResourceUsage_Preprocessor_HeaderSearch,
6605 pp.getHeaderSearchInfo().getTotalMemory());
6606
6607 CXTUResourceUsage usage = { (void*) entries.get(),
6608 (unsigned) entries->size(),
6609 entries->size() ? &(*entries)[0] : 0 };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006610 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006611 return usage;
6612}
6613
6614void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6615 if (usage.data)
6616 delete (MemUsageEntries*) usage.data;
6617}
6618
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006619CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6620 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006621 skipped->count = 0;
6622 skipped->ranges = 0;
6623
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006624 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006625 LOG_BAD_TU(TU);
6626 return skipped;
6627 }
6628
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006629 if (!file)
6630 return skipped;
6631
6632 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6633 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6634 if (!ppRec)
6635 return skipped;
6636
6637 ASTContext &Ctx = astUnit->getASTContext();
6638 SourceManager &sm = Ctx.getSourceManager();
6639 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6640 FileID wantedFileID = sm.translateFile(fileEntry);
6641
6642 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6643 std::vector<SourceRange> wantedRanges;
6644 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6645 i != ei; ++i) {
6646 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6647 wantedRanges.push_back(*i);
6648 }
6649
6650 skipped->count = wantedRanges.size();
6651 skipped->ranges = new CXSourceRange[skipped->count];
6652 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6653 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6654
6655 return skipped;
6656}
6657
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006658void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6659 if (ranges) {
6660 delete[] ranges->ranges;
6661 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006662 }
6663}
6664
Guy Benyei11169dd2012-12-18 14:30:41 +00006665} // end extern "C"
6666
6667void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6668 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6669 for (unsigned I = 0; I != Usage.numEntries; ++I)
6670 fprintf(stderr, " %s: %lu\n",
6671 clang_getTUResourceUsageName(Usage.entries[I].kind),
6672 Usage.entries[I].amount);
6673
6674 clang_disposeCXTUResourceUsage(Usage);
6675}
6676
6677//===----------------------------------------------------------------------===//
6678// Misc. utility functions.
6679//===----------------------------------------------------------------------===//
6680
6681/// Default to using an 8 MB stack size on "safety" threads.
6682static unsigned SafetyStackThreadSize = 8 << 20;
6683
6684namespace clang {
6685
6686bool RunSafely(llvm::CrashRecoveryContext &CRC,
6687 void (*Fn)(void*), void *UserData,
6688 unsigned Size) {
6689 if (!Size)
6690 Size = GetSafetyThreadStackSize();
6691 if (Size)
6692 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6693 return CRC.RunSafely(Fn, UserData);
6694}
6695
6696unsigned GetSafetyThreadStackSize() {
6697 return SafetyStackThreadSize;
6698}
6699
6700void SetSafetyThreadStackSize(unsigned Value) {
6701 SafetyStackThreadSize = Value;
6702}
6703
6704}
6705
6706void clang::setThreadBackgroundPriority() {
6707 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6708 return;
6709
6710 // FIXME: Move to llvm/Support and make it cross-platform.
6711#ifdef __APPLE__
6712 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6713#endif
6714}
6715
6716void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6717 if (!Unit)
6718 return;
6719
6720 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6721 DEnd = Unit->stored_diag_end();
6722 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006723 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006724 CXString Msg = clang_formatDiagnostic(&Diag,
6725 clang_defaultDiagnosticDisplayOptions());
6726 fprintf(stderr, "%s\n", clang_getCString(Msg));
6727 clang_disposeString(Msg);
6728 }
6729#ifdef LLVM_ON_WIN32
6730 // On Windows, force a flush, since there may be multiple copies of
6731 // stderr and stdout in the file system, all with different buffers
6732 // but writing to the same device.
6733 fflush(stderr);
6734#endif
6735}
6736
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006737MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6738 SourceLocation MacroDefLoc,
6739 CXTranslationUnit TU){
6740 if (MacroDefLoc.isInvalid() || !TU)
6741 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006742 if (!II.hadMacroDefinition())
6743 return 0;
6744
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006745 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006746 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006747 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006748 if (MD) {
6749 for (MacroDirective::DefInfo
6750 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6751 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6752 return Def.getMacroInfo();
6753 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006754 }
6755
6756 return 0;
6757}
6758
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006759const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6760 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006761 if (!MacroDef || !TU)
6762 return 0;
6763 const IdentifierInfo *II = MacroDef->getName();
6764 if (!II)
6765 return 0;
6766
6767 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6768}
6769
6770MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6771 const Token &Tok,
6772 CXTranslationUnit TU) {
6773 if (!MI || !TU)
6774 return 0;
6775 if (Tok.isNot(tok::raw_identifier))
6776 return 0;
6777
6778 if (MI->getNumTokens() == 0)
6779 return 0;
6780 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6781 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006782 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006783
6784 // Check that the token is inside the definition and not its argument list.
6785 SourceManager &SM = Unit->getSourceManager();
6786 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6787 return 0;
6788 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6789 return 0;
6790
6791 Preprocessor &PP = Unit->getPreprocessor();
6792 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6793 if (!PPRec)
6794 return 0;
6795
6796 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6797 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6798 if (!II.hadMacroDefinition())
6799 return 0;
6800
6801 // Check that the identifier is not one of the macro arguments.
6802 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6803 return 0;
6804
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006805 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6806 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006807 return 0;
6808
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006809 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006810}
6811
6812MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6813 SourceLocation Loc,
6814 CXTranslationUnit TU) {
6815 if (Loc.isInvalid() || !MI || !TU)
6816 return 0;
6817
6818 if (MI->getNumTokens() == 0)
6819 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006820 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006821 Preprocessor &PP = Unit->getPreprocessor();
6822 if (!PP.getPreprocessingRecord())
6823 return 0;
6824 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6825 Token Tok;
6826 if (PP.getRawToken(Loc, Tok))
6827 return 0;
6828
6829 return checkForMacroInMacroDefinition(MI, Tok, TU);
6830}
6831
Guy Benyei11169dd2012-12-18 14:30:41 +00006832extern "C" {
6833
6834CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006835 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006836}
6837
6838} // end: extern "C"
6839
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006840Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6841 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006842 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006843 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006844 if (Unit->isMainFileAST())
6845 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006846 return *this;
6847 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006848 } else {
6849 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006850 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006851 return *this;
6852}
6853
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006854Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6855 *this << FE->getName();
6856 return *this;
6857}
6858
6859Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6860 CXString cursorName = clang_getCursorDisplayName(cursor);
6861 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6862 clang_disposeString(cursorName);
6863 return *this;
6864}
6865
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006866Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6867 CXFile File;
6868 unsigned Line, Column;
6869 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6870 CXString FileName = clang_getFileName(File);
6871 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6872 clang_disposeString(FileName);
6873 return *this;
6874}
6875
6876Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6877 CXSourceLocation BLoc = clang_getRangeStart(range);
6878 CXSourceLocation ELoc = clang_getRangeEnd(range);
6879
6880 CXFile BFile;
6881 unsigned BLine, BColumn;
6882 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6883
6884 CXFile EFile;
6885 unsigned ELine, EColumn;
6886 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6887
6888 CXString BFileName = clang_getFileName(BFile);
6889 if (BFile == EFile) {
6890 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6891 BLine, BColumn, ELine, EColumn);
6892 } else {
6893 CXString EFileName = clang_getFileName(EFile);
6894 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6895 BLine, BColumn)
6896 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6897 ELine, EColumn);
6898 clang_disposeString(EFileName);
6899 }
6900 clang_disposeString(BFileName);
6901 return *this;
6902}
6903
6904Logger &cxindex::Logger::operator<<(CXString Str) {
6905 *this << clang_getCString(Str);
6906 return *this;
6907}
6908
6909Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6910 LogOS << Fmt;
6911 return *this;
6912}
6913
6914cxindex::Logger::~Logger() {
6915 LogOS.flush();
6916
6917 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6918
6919 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6920
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006921 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006922 OS << "[libclang:" << Name << ':';
6923
6924 // FIXME: Portability.
6925#if HAVE_PTHREAD_H && __APPLE__
6926 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6927 OS << tid << ':';
6928#endif
6929
6930 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6931 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6932 OS << Msg.str() << '\n';
6933
6934 if (Trace) {
6935 llvm::sys::PrintStackTrace(stderr);
6936 OS << "--------------------------------------------------\n";
6937 }
6938}