blob: d98acb197fa140e796a35d856aeff191c6143b7f [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXComment.h"
19#include "CXCursor.h"
20#include "CXSourceLocation.h"
21#include "CXString.h"
22#include "CXTranslationUnit.h"
23#include "CXType.h"
24#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000025#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000026#include "clang/AST/StmtVisitor.h"
27#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000028#include "clang/Basic/DiagnosticCategories.h"
29#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000030#include "clang/Basic/Version.h"
31#include "clang/Frontend/ASTUnit.h"
32#include "clang/Frontend/CompilerInstance.h"
33#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000034#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000035#include "clang/Lex/HeaderSearch.h"
36#include "clang/Lex/Lexer.h"
37#include "clang/Lex/PreprocessingRecord.h"
38#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000039#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000040#include "llvm/ADT/Optional.h"
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/StringSwitch.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000043#include "llvm/Config/config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000044#include "llvm/Support/Compiler.h"
45#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000046#include "llvm/Support/Format.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000047#include "llvm/Support/MemoryBuffer.h"
48#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000049#include "llvm/Support/Program.h"
50#include "llvm/Support/SaveAndRestore.h"
51#include "llvm/Support/Signals.h"
52#include "llvm/Support/Threading.h"
53#include "llvm/Support/Timer.h"
54#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000055
56#if HAVE_PTHREAD_H
57#include <pthread.h>
58#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000059
60using namespace clang;
61using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000062using namespace clang::cxtu;
63using namespace clang::cxindex;
64
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000065CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
66 if (!AU)
Guy Benyei11169dd2012-12-18 14:30:41 +000067 return 0;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000068 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000069 CXTranslationUnit D = new CXTranslationUnitImpl();
70 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000071 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000072 D->StringPool = new cxstring::CXStringPool();
Guy Benyei11169dd2012-12-18 14:30:41 +000073 D->Diagnostics = 0;
74 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Dmitri Gribenko9e605112013-11-13 22:16:51 +000075 D->CommentToXML = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +000076 return D;
77}
78
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000079bool cxtu::isASTReadError(ASTUnit *AU) {
80 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
81 DEnd = AU->stored_diag_end();
82 D != DEnd; ++D) {
83 if (D->getLevel() >= DiagnosticsEngine::Error &&
84 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
85 diag::DiagCat_AST_Deserialization_Issue)
86 return true;
87 }
88 return false;
89}
90
Guy Benyei11169dd2012-12-18 14:30:41 +000091cxtu::CXTUOwner::~CXTUOwner() {
92 if (TU)
93 clang_disposeTranslationUnit(TU);
94}
95
96/// \brief Compare two source ranges to determine their relative position in
97/// the translation unit.
98static RangeComparisonResult RangeCompare(SourceManager &SM,
99 SourceRange R1,
100 SourceRange R2) {
101 assert(R1.isValid() && "First range is invalid?");
102 assert(R2.isValid() && "Second range is invalid?");
103 if (R1.getEnd() != R2.getBegin() &&
104 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
105 return RangeBefore;
106 if (R2.getEnd() != R1.getBegin() &&
107 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
108 return RangeAfter;
109 return RangeOverlap;
110}
111
112/// \brief Determine if a source location falls within, before, or after a
113/// a given source range.
114static RangeComparisonResult LocationCompare(SourceManager &SM,
115 SourceLocation L, SourceRange R) {
116 assert(R.isValid() && "First range is invalid?");
117 assert(L.isValid() && "Second range is invalid?");
118 if (L == R.getBegin() || L == R.getEnd())
119 return RangeOverlap;
120 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
121 return RangeBefore;
122 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
123 return RangeAfter;
124 return RangeOverlap;
125}
126
127/// \brief Translate a Clang source range into a CIndex source range.
128///
129/// Clang internally represents ranges where the end location points to the
130/// start of the token at the end. However, for external clients it is more
131/// useful to have a CXSourceRange be a proper half-open interval. This routine
132/// does the appropriate translation.
133CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
134 const LangOptions &LangOpts,
135 const CharSourceRange &R) {
136 // We want the last character in this location, so we will adjust the
137 // location accordingly.
138 SourceLocation EndLoc = R.getEnd();
139 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
140 EndLoc = SM.getExpansionRange(EndLoc).second;
141 if (R.isTokenRange() && !EndLoc.isInvalid()) {
142 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
143 SM, LangOpts);
144 EndLoc = EndLoc.getLocWithOffset(Length);
145 }
146
Bill Wendlingeade3622013-01-23 08:25:41 +0000147 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000148 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000149 R.getBegin().getRawEncoding(),
150 EndLoc.getRawEncoding()
151 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000152 return Result;
153}
154
155//===----------------------------------------------------------------------===//
156// Cursor visitor.
157//===----------------------------------------------------------------------===//
158
159static SourceRange getRawCursorExtent(CXCursor C);
160static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
161
162
163RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
164 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
165}
166
167/// \brief Visit the given cursor and, if requested by the visitor,
168/// its children.
169///
170/// \param Cursor the cursor to visit.
171///
172/// \param CheckedRegionOfInterest if true, then the caller already checked
173/// that this cursor is within the region of interest.
174///
175/// \returns true if the visitation should be aborted, false if it
176/// should continue.
177bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
178 if (clang_isInvalid(Cursor.kind))
179 return false;
180
181 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000182 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000183 if (!D) {
184 assert(0 && "Invalid declaration cursor");
185 return true; // abort.
186 }
187
188 // Ignore implicit declarations, unless it's an objc method because
189 // currently we should report implicit methods for properties when indexing.
190 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
191 return false;
192 }
193
194 // If we have a range of interest, and this cursor doesn't intersect with it,
195 // we're done.
196 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
197 SourceRange Range = getRawCursorExtent(Cursor);
198 if (Range.isInvalid() || CompareRegionOfInterest(Range))
199 return false;
200 }
201
202 switch (Visitor(Cursor, Parent, ClientData)) {
203 case CXChildVisit_Break:
204 return true;
205
206 case CXChildVisit_Continue:
207 return false;
208
209 case CXChildVisit_Recurse: {
210 bool ret = VisitChildren(Cursor);
211 if (PostChildrenVisitor)
212 if (PostChildrenVisitor(Cursor, ClientData))
213 return true;
214 return ret;
215 }
216 }
217
218 llvm_unreachable("Invalid CXChildVisitResult!");
219}
220
221static bool visitPreprocessedEntitiesInRange(SourceRange R,
222 PreprocessingRecord &PPRec,
223 CursorVisitor &Visitor) {
224 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
225 FileID FID;
226
227 if (!Visitor.shouldVisitIncludedEntities()) {
228 // If the begin/end of the range lie in the same FileID, do the optimization
229 // where we skip preprocessed entities that do not come from the same FileID.
230 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
231 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
232 FID = FileID();
233 }
234
235 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
236 Entities = PPRec.getPreprocessedEntitiesInRange(R);
237 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
238 PPRec, FID);
239}
240
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000241bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000242 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000243 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000244
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000245 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000246 SourceManager &SM = Unit->getSourceManager();
247
248 std::pair<FileID, unsigned>
249 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
250 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
251
252 if (End.first != Begin.first) {
253 // If the end does not reside in the same file, try to recover by
254 // picking the end of the file of begin location.
255 End.first = Begin.first;
256 End.second = SM.getFileIDSize(Begin.first);
257 }
258
259 assert(Begin.first == End.first);
260 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000261 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000262
263 FileID File = Begin.first;
264 unsigned Offset = Begin.second;
265 unsigned Length = End.second - Begin.second;
266
267 if (!VisitDeclsOnly && !VisitPreprocessorLast)
268 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000269 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000270
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000271 if (visitDeclsFromFileRegion(File, Offset, Length))
272 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000273
274 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000275 return visitPreprocessedEntitiesInRegion();
276
277 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000278}
279
280static bool isInLexicalContext(Decl *D, DeclContext *DC) {
281 if (!DC)
282 return false;
283
284 for (DeclContext *DeclDC = D->getLexicalDeclContext();
285 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
286 if (DeclDC == DC)
287 return true;
288 }
289 return false;
290}
291
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000292bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000293 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000294 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000295 SourceManager &SM = Unit->getSourceManager();
296 SourceRange Range = RegionOfInterest;
297
298 SmallVector<Decl *, 16> Decls;
299 Unit->findFileRegionDecls(File, Offset, Length, Decls);
300
301 // If we didn't find any file level decls for the file, try looking at the
302 // file that it was included from.
303 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
304 bool Invalid = false;
305 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
306 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000307 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000308
309 SourceLocation Outer;
310 if (SLEntry.isFile())
311 Outer = SLEntry.getFile().getIncludeLoc();
312 else
313 Outer = SLEntry.getExpansion().getExpansionLocStart();
314 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000315 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000316
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000317 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000318 Length = 0;
319 Unit->findFileRegionDecls(File, Offset, Length, Decls);
320 }
321
322 assert(!Decls.empty());
323
324 bool VisitedAtLeastOnce = false;
325 DeclContext *CurDC = 0;
Craig Topper2341c0d2013-07-04 03:08:24 +0000326 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
327 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000328 Decl *D = *DIt;
329 if (D->getSourceRange().isInvalid())
330 continue;
331
332 if (isInLexicalContext(D, CurDC))
333 continue;
334
335 CurDC = dyn_cast<DeclContext>(D);
336
337 if (TagDecl *TD = dyn_cast<TagDecl>(D))
338 if (!TD->isFreeStanding())
339 continue;
340
341 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
342 if (CompRes == RangeBefore)
343 continue;
344 if (CompRes == RangeAfter)
345 break;
346
347 assert(CompRes == RangeOverlap);
348 VisitedAtLeastOnce = true;
349
350 if (isa<ObjCContainerDecl>(D)) {
351 FileDI_current = &DIt;
352 FileDE_current = DE;
353 } else {
354 FileDI_current = 0;
355 }
356
357 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000358 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000359 }
360
361 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000362 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000363
364 // No Decls overlapped with the range. Move up the lexical context until there
365 // is a context that contains the range or we reach the translation unit
366 // level.
367 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
368 : (*(DIt-1))->getLexicalDeclContext();
369
370 while (DC && !DC->isTranslationUnit()) {
371 Decl *D = cast<Decl>(DC);
372 SourceRange CurDeclRange = D->getSourceRange();
373 if (CurDeclRange.isInvalid())
374 break;
375
376 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000377 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
378 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000379 }
380
381 DC = D->getLexicalDeclContext();
382 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000383
384 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000385}
386
387bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
388 if (!AU->getPreprocessor().getPreprocessingRecord())
389 return false;
390
391 PreprocessingRecord &PPRec
392 = *AU->getPreprocessor().getPreprocessingRecord();
393 SourceManager &SM = AU->getSourceManager();
394
395 if (RegionOfInterest.isValid()) {
396 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
397 SourceLocation B = MappedRange.getBegin();
398 SourceLocation E = MappedRange.getEnd();
399
400 if (AU->isInPreambleFileID(B)) {
401 if (SM.isLoadedSourceLocation(E))
402 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
403 PPRec, *this);
404
405 // Beginning of range lies in the preamble but it also extends beyond
406 // it into the main file. Split the range into 2 parts, one covering
407 // the preamble and another covering the main file. This allows subsequent
408 // calls to visitPreprocessedEntitiesInRange to accept a source range that
409 // lies in the same FileID, allowing it to skip preprocessed entities that
410 // do not come from the same FileID.
411 bool breaked =
412 visitPreprocessedEntitiesInRange(
413 SourceRange(B, AU->getEndOfPreambleFileID()),
414 PPRec, *this);
415 if (breaked) return true;
416 return visitPreprocessedEntitiesInRange(
417 SourceRange(AU->getStartOfMainFileID(), E),
418 PPRec, *this);
419 }
420
421 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
422 }
423
424 bool OnlyLocalDecls
425 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
426
427 if (OnlyLocalDecls)
428 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
429 PPRec);
430
431 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
432}
433
434template<typename InputIterator>
435bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
436 InputIterator Last,
437 PreprocessingRecord &PPRec,
438 FileID FID) {
439 for (; First != Last; ++First) {
440 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
441 continue;
442
443 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000444 if (!PPE)
445 continue;
446
Guy Benyei11169dd2012-12-18 14:30:41 +0000447 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
448 if (Visit(MakeMacroExpansionCursor(ME, TU)))
449 return true;
450
451 continue;
452 }
453
454 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
455 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
456 return true;
457
458 continue;
459 }
460
461 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
462 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
463 return true;
464
465 continue;
466 }
467 }
468
469 return false;
470}
471
472/// \brief Visit the children of the given cursor.
473///
474/// \returns true if the visitation should be aborted, false if it
475/// should continue.
476bool CursorVisitor::VisitChildren(CXCursor Cursor) {
477 if (clang_isReference(Cursor.kind) &&
478 Cursor.kind != CXCursor_CXXBaseSpecifier) {
479 // By definition, references have no children.
480 return false;
481 }
482
483 // Set the Parent field to Cursor, then back to its old value once we're
484 // done.
485 SetParentRAII SetParent(Parent, StmtParent, Cursor);
486
487 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000488 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000489 if (!D)
490 return false;
491
492 return VisitAttributes(D) || Visit(D);
493 }
494
495 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000496 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000497 return Visit(S);
498
499 return false;
500 }
501
502 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000503 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000504 return Visit(E);
505
506 return false;
507 }
508
509 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000510 CXTranslationUnit TU = getCursorTU(Cursor);
511 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000512
513 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
514 for (unsigned I = 0; I != 2; ++I) {
515 if (VisitOrder[I]) {
516 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
517 RegionOfInterest.isInvalid()) {
518 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
519 TLEnd = CXXUnit->top_level_end();
520 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000521 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000522 return true;
523 }
524 } else if (VisitDeclContext(
525 CXXUnit->getASTContext().getTranslationUnitDecl()))
526 return true;
527 continue;
528 }
529
530 // Walk the preprocessing record.
531 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
532 visitPreprocessedEntitiesInRegion();
533 }
534
535 return false;
536 }
537
538 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000539 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000540 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
541 return Visit(BaseTSInfo->getTypeLoc());
542 }
543 }
544 }
545
546 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000547 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000548 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000549 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000550 return Visit(cxcursor::MakeCursorObjCClassRef(
551 ObjT->getInterface(),
552 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000553 }
554
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000555 // If pointing inside a macro definition, check if the token is an identifier
556 // that was ever defined as a macro. In such a case, create a "pseudo" macro
557 // expansion cursor for that token.
558 SourceLocation BeginLoc = RegionOfInterest.getBegin();
559 if (Cursor.kind == CXCursor_MacroDefinition &&
560 BeginLoc == RegionOfInterest.getEnd()) {
561 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000562 const MacroInfo *MI =
563 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000564 if (MacroDefinition *MacroDef =
565 checkForMacroInMacroDefinition(MI, Loc, TU))
566 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
567 }
568
Guy Benyei11169dd2012-12-18 14:30:41 +0000569 // Nothing to visit at the moment.
570 return false;
571}
572
573bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
574 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
575 if (Visit(TSInfo->getTypeLoc()))
576 return true;
577
578 if (Stmt *Body = B->getBody())
579 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
580
581 return false;
582}
583
Ted Kremenek03325582013-02-21 01:29:01 +0000584Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000585 if (RegionOfInterest.isValid()) {
586 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
587 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000588 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000589
590 switch (CompareRegionOfInterest(Range)) {
591 case RangeBefore:
592 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000593 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000594
595 case RangeAfter:
596 // This declaration comes after the region of interest; we're done.
597 return false;
598
599 case RangeOverlap:
600 // This declaration overlaps the region of interest; visit it.
601 break;
602 }
603 }
604 return true;
605}
606
607bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
608 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
609
610 // FIXME: Eventually remove. This part of a hack to support proper
611 // iteration over all Decls contained lexically within an ObjC container.
612 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
613 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
614
615 for ( ; I != E; ++I) {
616 Decl *D = *I;
617 if (D->getLexicalDeclContext() != DC)
618 continue;
619 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
620
621 // Ignore synthesized ivars here, otherwise if we have something like:
622 // @synthesize prop = _prop;
623 // and '_prop' is not declared, we will encounter a '_prop' ivar before
624 // encountering the 'prop' synthesize declaration and we will think that
625 // we passed the region-of-interest.
626 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
627 if (ivarD->getSynthesize())
628 continue;
629 }
630
631 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
632 // declarations is a mismatch with the compiler semantics.
633 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
634 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
635 if (!ID->isThisDeclarationADefinition())
636 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
637
638 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
639 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
640 if (!PD->isThisDeclarationADefinition())
641 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
642 }
643
Ted Kremenek03325582013-02-21 01:29:01 +0000644 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000645 if (!V.hasValue())
646 continue;
647 if (!V.getValue())
648 return false;
649 if (Visit(Cursor, true))
650 return true;
651 }
652 return false;
653}
654
655bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
656 llvm_unreachable("Translation units are visited directly by Visit()");
657}
658
659bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
660 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
661 return Visit(TSInfo->getTypeLoc());
662
663 return false;
664}
665
666bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
667 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
668 return Visit(TSInfo->getTypeLoc());
669
670 return false;
671}
672
673bool CursorVisitor::VisitTagDecl(TagDecl *D) {
674 return VisitDeclContext(D);
675}
676
677bool CursorVisitor::VisitClassTemplateSpecializationDecl(
678 ClassTemplateSpecializationDecl *D) {
679 bool ShouldVisitBody = false;
680 switch (D->getSpecializationKind()) {
681 case TSK_Undeclared:
682 case TSK_ImplicitInstantiation:
683 // Nothing to visit
684 return false;
685
686 case TSK_ExplicitInstantiationDeclaration:
687 case TSK_ExplicitInstantiationDefinition:
688 break;
689
690 case TSK_ExplicitSpecialization:
691 ShouldVisitBody = true;
692 break;
693 }
694
695 // Visit the template arguments used in the specialization.
696 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
697 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000698 if (TemplateSpecializationTypeLoc TSTLoc =
699 TL.getAs<TemplateSpecializationTypeLoc>()) {
700 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
701 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000702 return true;
703 }
704 }
705
706 if (ShouldVisitBody && VisitCXXRecordDecl(D))
707 return true;
708
709 return false;
710}
711
712bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
713 ClassTemplatePartialSpecializationDecl *D) {
714 // FIXME: Visit the "outer" template parameter lists on the TagDecl
715 // before visiting these template parameters.
716 if (VisitTemplateParameters(D->getTemplateParameters()))
717 return true;
718
719 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000720 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
721 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
722 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000723 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
724 return true;
725
726 return VisitCXXRecordDecl(D);
727}
728
729bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
730 // Visit the default argument.
731 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
732 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
733 if (Visit(DefArg->getTypeLoc()))
734 return true;
735
736 return false;
737}
738
739bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
740 if (Expr *Init = D->getInitExpr())
741 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
742 return false;
743}
744
745bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000746 unsigned NumParamList = DD->getNumTemplateParameterLists();
747 for (unsigned i = 0; i < NumParamList; i++) {
748 TemplateParameterList* Params = DD->getTemplateParameterList(i);
749 if (VisitTemplateParameters(Params))
750 return true;
751 }
752
Guy Benyei11169dd2012-12-18 14:30:41 +0000753 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
754 if (Visit(TSInfo->getTypeLoc()))
755 return true;
756
757 // Visit the nested-name-specifier, if present.
758 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
759 if (VisitNestedNameSpecifierLoc(QualifierLoc))
760 return true;
761
762 return false;
763}
764
765/// \brief Compare two base or member initializers based on their source order.
Benjamin Kramer04bf1872013-09-22 14:10:29 +0000766static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
767 CXXCtorInitializer *const *Y) {
768 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
Guy Benyei11169dd2012-12-18 14:30:41 +0000769}
770
771bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000772 unsigned NumParamList = ND->getNumTemplateParameterLists();
773 for (unsigned i = 0; i < NumParamList; i++) {
774 TemplateParameterList* Params = ND->getTemplateParameterList(i);
775 if (VisitTemplateParameters(Params))
776 return true;
777 }
778
Guy Benyei11169dd2012-12-18 14:30:41 +0000779 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
780 // Visit the function declaration's syntactic components in the order
781 // written. This requires a bit of work.
782 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000783 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000784
785 // If we have a function declared directly (without the use of a typedef),
786 // visit just the return type. Otherwise, just visit the function's type
787 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000788 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000789 (!FTL && Visit(TL)))
790 return true;
791
792 // Visit the nested-name-specifier, if present.
793 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
794 if (VisitNestedNameSpecifierLoc(QualifierLoc))
795 return true;
796
797 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000798 if (!isa<CXXDestructorDecl>(ND))
799 if (VisitDeclarationNameInfo(ND->getNameInfo()))
800 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000801
802 // FIXME: Visit explicitly-specified template arguments!
803
804 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000805 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000806 return true;
807
Bill Wendling44426052012-12-20 19:22:21 +0000808 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000809 }
810
811 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
812 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
813 // Find the initializers that were written in the source.
814 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
815 for (CXXConstructorDecl::init_iterator I = Constructor->init_begin(),
816 IEnd = Constructor->init_end();
817 I != IEnd; ++I) {
818 if (!(*I)->isWritten())
819 continue;
820
821 WrittenInits.push_back(*I);
822 }
823
824 // Sort the initializers in source order
825 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
826 &CompareCXXCtorInitializers);
827
828 // Visit the initializers in source order
829 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
830 CXXCtorInitializer *Init = WrittenInits[I];
831 if (Init->isAnyMemberInitializer()) {
832 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
833 Init->getMemberLocation(), TU)))
834 return true;
835 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
836 if (Visit(TInfo->getTypeLoc()))
837 return true;
838 }
839
840 // Visit the initializer value.
841 if (Expr *Initializer = Init->getInit())
842 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
843 return true;
844 }
845 }
846
847 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
848 return true;
849 }
850
851 return false;
852}
853
854bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
855 if (VisitDeclaratorDecl(D))
856 return true;
857
858 if (Expr *BitWidth = D->getBitWidth())
859 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
860
861 return false;
862}
863
864bool CursorVisitor::VisitVarDecl(VarDecl *D) {
865 if (VisitDeclaratorDecl(D))
866 return true;
867
868 if (Expr *Init = D->getInit())
869 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
870
871 return false;
872}
873
874bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
875 if (VisitDeclaratorDecl(D))
876 return true;
877
878 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
879 if (Expr *DefArg = D->getDefaultArgument())
880 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
881
882 return false;
883}
884
885bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
886 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
887 // before visiting these template parameters.
888 if (VisitTemplateParameters(D->getTemplateParameters()))
889 return true;
890
891 return VisitFunctionDecl(D->getTemplatedDecl());
892}
893
894bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
895 // FIXME: Visit the "outer" template parameter lists on the TagDecl
896 // before visiting these template parameters.
897 if (VisitTemplateParameters(D->getTemplateParameters()))
898 return true;
899
900 return VisitCXXRecordDecl(D->getTemplatedDecl());
901}
902
903bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
904 if (VisitTemplateParameters(D->getTemplateParameters()))
905 return true;
906
907 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
908 VisitTemplateArgumentLoc(D->getDefaultArgument()))
909 return true;
910
911 return false;
912}
913
914bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000915 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000916 if (Visit(TSInfo->getTypeLoc()))
917 return true;
918
Aaron Ballman43b68be2014-03-07 17:50:17 +0000919 for (const auto *P : ND->params()) {
920 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000921 return true;
922 }
923
924 if (ND->isThisDeclarationADefinition() &&
925 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
926 return true;
927
928 return false;
929}
930
931template <typename DeclIt>
932static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
933 SourceManager &SM, SourceLocation EndLoc,
934 SmallVectorImpl<Decl *> &Decls) {
935 DeclIt next = *DI_current;
936 while (++next != DE_current) {
937 Decl *D_next = *next;
938 if (!D_next)
939 break;
940 SourceLocation L = D_next->getLocStart();
941 if (!L.isValid())
942 break;
943 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
944 *DI_current = next;
945 Decls.push_back(D_next);
946 continue;
947 }
948 break;
949 }
950}
951
Guy Benyei11169dd2012-12-18 14:30:41 +0000952bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
953 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
954 // an @implementation can lexically contain Decls that are not properly
955 // nested in the AST. When we identify such cases, we need to retrofit
956 // this nesting here.
957 if (!DI_current && !FileDI_current)
958 return VisitDeclContext(D);
959
960 // Scan the Decls that immediately come after the container
961 // in the current DeclContext. If any fall within the
962 // container's lexical region, stash them into a vector
963 // for later processing.
964 SmallVector<Decl *, 24> DeclsInContainer;
965 SourceLocation EndLoc = D->getSourceRange().getEnd();
966 SourceManager &SM = AU->getSourceManager();
967 if (EndLoc.isValid()) {
968 if (DI_current) {
969 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
970 DeclsInContainer);
971 } else {
972 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
973 DeclsInContainer);
974 }
975 }
976
977 // The common case.
978 if (DeclsInContainer.empty())
979 return VisitDeclContext(D);
980
981 // Get all the Decls in the DeclContext, and sort them with the
982 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000983 for (auto *SubDecl : D->decls()) {
984 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
985 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000986 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000987 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000988 }
989
990 // Now sort the Decls so that they appear in lexical order.
991 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000992 [&SM](Decl *A, Decl *B) {
993 SourceLocation L_A = A->getLocStart();
994 SourceLocation L_B = B->getLocStart();
995 assert(L_A.isValid() && L_B.isValid());
996 return SM.isBeforeInTranslationUnit(L_A, L_B);
997 });
Guy Benyei11169dd2012-12-18 14:30:41 +0000998
999 // Now visit the decls.
1000 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1001 E = DeclsInContainer.end(); I != E; ++I) {
1002 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001003 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001004 if (!V.hasValue())
1005 continue;
1006 if (!V.getValue())
1007 return false;
1008 if (Visit(Cursor, true))
1009 return true;
1010 }
1011 return false;
1012}
1013
1014bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1015 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1016 TU)))
1017 return true;
1018
1019 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1020 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1021 E = ND->protocol_end(); I != E; ++I, ++PL)
1022 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1023 return true;
1024
1025 return VisitObjCContainerDecl(ND);
1026}
1027
1028bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1029 if (!PID->isThisDeclarationADefinition())
1030 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1031
1032 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1033 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1034 E = PID->protocol_end(); I != E; ++I, ++PL)
1035 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1036 return true;
1037
1038 return VisitObjCContainerDecl(PID);
1039}
1040
1041bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1042 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1043 return true;
1044
1045 // FIXME: This implements a workaround with @property declarations also being
1046 // installed in the DeclContext for the @interface. Eventually this code
1047 // should be removed.
1048 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1049 if (!CDecl || !CDecl->IsClassExtension())
1050 return false;
1051
1052 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1053 if (!ID)
1054 return false;
1055
1056 IdentifierInfo *PropertyId = PD->getIdentifier();
1057 ObjCPropertyDecl *prevDecl =
1058 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1059
1060 if (!prevDecl)
1061 return false;
1062
1063 // Visit synthesized methods since they will be skipped when visiting
1064 // the @interface.
1065 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1066 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1067 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1068 return true;
1069
1070 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1071 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1072 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1073 return true;
1074
1075 return false;
1076}
1077
1078bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1079 if (!D->isThisDeclarationADefinition()) {
1080 // Forward declaration is treated like a reference.
1081 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1082 }
1083
1084 // Issue callbacks for super class.
1085 if (D->getSuperClass() &&
1086 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1087 D->getSuperClassLoc(),
1088 TU)))
1089 return true;
1090
1091 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1092 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1093 E = D->protocol_end(); I != E; ++I, ++PL)
1094 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1095 return true;
1096
1097 return VisitObjCContainerDecl(D);
1098}
1099
1100bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1101 return VisitObjCContainerDecl(D);
1102}
1103
1104bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1105 // 'ID' could be null when dealing with invalid code.
1106 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1107 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1108 return true;
1109
1110 return VisitObjCImplDecl(D);
1111}
1112
1113bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1114#if 0
1115 // Issue callbacks for super class.
1116 // FIXME: No source location information!
1117 if (D->getSuperClass() &&
1118 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1119 D->getSuperClassLoc(),
1120 TU)))
1121 return true;
1122#endif
1123
1124 return VisitObjCImplDecl(D);
1125}
1126
1127bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1128 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1129 if (PD->isIvarNameSpecified())
1130 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1131
1132 return false;
1133}
1134
1135bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1136 return VisitDeclContext(D);
1137}
1138
1139bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1140 // Visit nested-name-specifier.
1141 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1142 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1143 return true;
1144
1145 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1146 D->getTargetNameLoc(), TU));
1147}
1148
1149bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1150 // Visit nested-name-specifier.
1151 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1152 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1153 return true;
1154 }
1155
1156 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1157 return true;
1158
1159 return VisitDeclarationNameInfo(D->getNameInfo());
1160}
1161
1162bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1163 // Visit nested-name-specifier.
1164 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1165 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1166 return true;
1167
1168 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1169 D->getIdentLocation(), TU));
1170}
1171
1172bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1173 // Visit nested-name-specifier.
1174 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1175 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1176 return true;
1177 }
1178
1179 return VisitDeclarationNameInfo(D->getNameInfo());
1180}
1181
1182bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1183 UnresolvedUsingTypenameDecl *D) {
1184 // Visit nested-name-specifier.
1185 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1186 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1187 return true;
1188
1189 return false;
1190}
1191
1192bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1193 switch (Name.getName().getNameKind()) {
1194 case clang::DeclarationName::Identifier:
1195 case clang::DeclarationName::CXXLiteralOperatorName:
1196 case clang::DeclarationName::CXXOperatorName:
1197 case clang::DeclarationName::CXXUsingDirective:
1198 return false;
1199
1200 case clang::DeclarationName::CXXConstructorName:
1201 case clang::DeclarationName::CXXDestructorName:
1202 case clang::DeclarationName::CXXConversionFunctionName:
1203 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1204 return Visit(TSInfo->getTypeLoc());
1205 return false;
1206
1207 case clang::DeclarationName::ObjCZeroArgSelector:
1208 case clang::DeclarationName::ObjCOneArgSelector:
1209 case clang::DeclarationName::ObjCMultiArgSelector:
1210 // FIXME: Per-identifier location info?
1211 return false;
1212 }
1213
1214 llvm_unreachable("Invalid DeclarationName::Kind!");
1215}
1216
1217bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1218 SourceRange Range) {
1219 // FIXME: This whole routine is a hack to work around the lack of proper
1220 // source information in nested-name-specifiers (PR5791). Since we do have
1221 // a beginning source location, we can visit the first component of the
1222 // nested-name-specifier, if it's a single-token component.
1223 if (!NNS)
1224 return false;
1225
1226 // Get the first component in the nested-name-specifier.
1227 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1228 NNS = Prefix;
1229
1230 switch (NNS->getKind()) {
1231 case NestedNameSpecifier::Namespace:
1232 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1233 TU));
1234
1235 case NestedNameSpecifier::NamespaceAlias:
1236 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1237 Range.getBegin(), TU));
1238
1239 case NestedNameSpecifier::TypeSpec: {
1240 // If the type has a form where we know that the beginning of the source
1241 // range matches up with a reference cursor. Visit the appropriate reference
1242 // cursor.
1243 const Type *T = NNS->getAsType();
1244 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1245 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1246 if (const TagType *Tag = dyn_cast<TagType>(T))
1247 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1248 if (const TemplateSpecializationType *TST
1249 = dyn_cast<TemplateSpecializationType>(T))
1250 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1251 break;
1252 }
1253
1254 case NestedNameSpecifier::TypeSpecWithTemplate:
1255 case NestedNameSpecifier::Global:
1256 case NestedNameSpecifier::Identifier:
1257 break;
1258 }
1259
1260 return false;
1261}
1262
1263bool
1264CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1265 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1266 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1267 Qualifiers.push_back(Qualifier);
1268
1269 while (!Qualifiers.empty()) {
1270 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1271 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1272 switch (NNS->getKind()) {
1273 case NestedNameSpecifier::Namespace:
1274 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1275 Q.getLocalBeginLoc(),
1276 TU)))
1277 return true;
1278
1279 break;
1280
1281 case NestedNameSpecifier::NamespaceAlias:
1282 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1283 Q.getLocalBeginLoc(),
1284 TU)))
1285 return true;
1286
1287 break;
1288
1289 case NestedNameSpecifier::TypeSpec:
1290 case NestedNameSpecifier::TypeSpecWithTemplate:
1291 if (Visit(Q.getTypeLoc()))
1292 return true;
1293
1294 break;
1295
1296 case NestedNameSpecifier::Global:
1297 case NestedNameSpecifier::Identifier:
1298 break;
1299 }
1300 }
1301
1302 return false;
1303}
1304
1305bool CursorVisitor::VisitTemplateParameters(
1306 const TemplateParameterList *Params) {
1307 if (!Params)
1308 return false;
1309
1310 for (TemplateParameterList::const_iterator P = Params->begin(),
1311 PEnd = Params->end();
1312 P != PEnd; ++P) {
1313 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1314 return true;
1315 }
1316
1317 return false;
1318}
1319
1320bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1321 switch (Name.getKind()) {
1322 case TemplateName::Template:
1323 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1324
1325 case TemplateName::OverloadedTemplate:
1326 // Visit the overloaded template set.
1327 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1328 return true;
1329
1330 return false;
1331
1332 case TemplateName::DependentTemplate:
1333 // FIXME: Visit nested-name-specifier.
1334 return false;
1335
1336 case TemplateName::QualifiedTemplate:
1337 // FIXME: Visit nested-name-specifier.
1338 return Visit(MakeCursorTemplateRef(
1339 Name.getAsQualifiedTemplateName()->getDecl(),
1340 Loc, TU));
1341
1342 case TemplateName::SubstTemplateTemplateParm:
1343 return Visit(MakeCursorTemplateRef(
1344 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1345 Loc, TU));
1346
1347 case TemplateName::SubstTemplateTemplateParmPack:
1348 return Visit(MakeCursorTemplateRef(
1349 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1350 Loc, TU));
1351 }
1352
1353 llvm_unreachable("Invalid TemplateName::Kind!");
1354}
1355
1356bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1357 switch (TAL.getArgument().getKind()) {
1358 case TemplateArgument::Null:
1359 case TemplateArgument::Integral:
1360 case TemplateArgument::Pack:
1361 return false;
1362
1363 case TemplateArgument::Type:
1364 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1365 return Visit(TSInfo->getTypeLoc());
1366 return false;
1367
1368 case TemplateArgument::Declaration:
1369 if (Expr *E = TAL.getSourceDeclExpression())
1370 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1371 return false;
1372
1373 case TemplateArgument::NullPtr:
1374 if (Expr *E = TAL.getSourceNullPtrExpression())
1375 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1376 return false;
1377
1378 case TemplateArgument::Expression:
1379 if (Expr *E = TAL.getSourceExpression())
1380 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1381 return false;
1382
1383 case TemplateArgument::Template:
1384 case TemplateArgument::TemplateExpansion:
1385 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1386 return true;
1387
1388 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1389 TAL.getTemplateNameLoc());
1390 }
1391
1392 llvm_unreachable("Invalid TemplateArgument::Kind!");
1393}
1394
1395bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1396 return VisitDeclContext(D);
1397}
1398
1399bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1400 return Visit(TL.getUnqualifiedLoc());
1401}
1402
1403bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1404 ASTContext &Context = AU->getASTContext();
1405
1406 // Some builtin types (such as Objective-C's "id", "sel", and
1407 // "Class") have associated declarations. Create cursors for those.
1408 QualType VisitType;
1409 switch (TL.getTypePtr()->getKind()) {
1410
1411 case BuiltinType::Void:
1412 case BuiltinType::NullPtr:
1413 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001414 case BuiltinType::OCLImage1d:
1415 case BuiltinType::OCLImage1dArray:
1416 case BuiltinType::OCLImage1dBuffer:
1417 case BuiltinType::OCLImage2d:
1418 case BuiltinType::OCLImage2dArray:
1419 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001420 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001421 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001422#define BUILTIN_TYPE(Id, SingletonId)
1423#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1424#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1425#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1426#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1427#include "clang/AST/BuiltinTypes.def"
1428 break;
1429
1430 case BuiltinType::ObjCId:
1431 VisitType = Context.getObjCIdType();
1432 break;
1433
1434 case BuiltinType::ObjCClass:
1435 VisitType = Context.getObjCClassType();
1436 break;
1437
1438 case BuiltinType::ObjCSel:
1439 VisitType = Context.getObjCSelType();
1440 break;
1441 }
1442
1443 if (!VisitType.isNull()) {
1444 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1445 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1446 TU));
1447 }
1448
1449 return false;
1450}
1451
1452bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1453 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1454}
1455
1456bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1457 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1458}
1459
1460bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1461 if (TL.isDefinition())
1462 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1463
1464 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1465}
1466
1467bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1468 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1469}
1470
1471bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1472 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1473 return true;
1474
1475 return false;
1476}
1477
1478bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1479 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1480 return true;
1481
1482 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1483 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1484 TU)))
1485 return true;
1486 }
1487
1488 return false;
1489}
1490
1491bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1492 return Visit(TL.getPointeeLoc());
1493}
1494
1495bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1496 return Visit(TL.getInnerLoc());
1497}
1498
1499bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1500 return Visit(TL.getPointeeLoc());
1501}
1502
1503bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1504 return Visit(TL.getPointeeLoc());
1505}
1506
1507bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1508 return Visit(TL.getPointeeLoc());
1509}
1510
1511bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1512 return Visit(TL.getPointeeLoc());
1513}
1514
1515bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1516 return Visit(TL.getPointeeLoc());
1517}
1518
1519bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1520 return Visit(TL.getModifiedLoc());
1521}
1522
1523bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1524 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001525 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001526 return true;
1527
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001528 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1529 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001530 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1531 return true;
1532
1533 return false;
1534}
1535
1536bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1537 if (Visit(TL.getElementLoc()))
1538 return true;
1539
1540 if (Expr *Size = TL.getSizeExpr())
1541 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1542
1543 return false;
1544}
1545
Reid Kleckner8a365022013-06-24 17:51:48 +00001546bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1547 return Visit(TL.getOriginalLoc());
1548}
1549
Reid Kleckner0503a872013-12-05 01:23:43 +00001550bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1551 return Visit(TL.getOriginalLoc());
1552}
1553
Guy Benyei11169dd2012-12-18 14:30:41 +00001554bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1555 TemplateSpecializationTypeLoc TL) {
1556 // Visit the template name.
1557 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1558 TL.getTemplateNameLoc()))
1559 return true;
1560
1561 // Visit the template arguments.
1562 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1563 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1564 return true;
1565
1566 return false;
1567}
1568
1569bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1570 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1571}
1572
1573bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1574 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1575 return Visit(TSInfo->getTypeLoc());
1576
1577 return false;
1578}
1579
1580bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1581 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1582 return Visit(TSInfo->getTypeLoc());
1583
1584 return false;
1585}
1586
1587bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1588 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1589 return true;
1590
1591 return false;
1592}
1593
1594bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1595 DependentTemplateSpecializationTypeLoc TL) {
1596 // Visit the nested-name-specifier, if there is one.
1597 if (TL.getQualifierLoc() &&
1598 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1599 return true;
1600
1601 // Visit the template arguments.
1602 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1603 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1604 return true;
1605
1606 return false;
1607}
1608
1609bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1610 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1611 return true;
1612
1613 return Visit(TL.getNamedTypeLoc());
1614}
1615
1616bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1617 return Visit(TL.getPatternLoc());
1618}
1619
1620bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1621 if (Expr *E = TL.getUnderlyingExpr())
1622 return Visit(MakeCXCursor(E, StmtParent, TU));
1623
1624 return false;
1625}
1626
1627bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1628 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1629}
1630
1631bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1632 return Visit(TL.getValueLoc());
1633}
1634
1635#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1636bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1637 return Visit##PARENT##Loc(TL); \
1638}
1639
1640DEFAULT_TYPELOC_IMPL(Complex, Type)
1641DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1642DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1643DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1644DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1645DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1646DEFAULT_TYPELOC_IMPL(Vector, Type)
1647DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1648DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1649DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1650DEFAULT_TYPELOC_IMPL(Record, TagType)
1651DEFAULT_TYPELOC_IMPL(Enum, TagType)
1652DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1653DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1654DEFAULT_TYPELOC_IMPL(Auto, Type)
1655
1656bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1657 // Visit the nested-name-specifier, if present.
1658 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1659 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1660 return true;
1661
1662 if (D->isCompleteDefinition()) {
1663 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1664 E = D->bases_end(); I != E; ++I) {
1665 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1666 return true;
1667 }
1668 }
1669
1670 return VisitTagDecl(D);
1671}
1672
1673bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballman7dce1a82014-03-07 13:13:38 +00001674 for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
1675 i != e; ++i)
1676 if (Visit(MakeCXCursor(*i, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001677 return true;
1678
1679 return false;
1680}
1681
1682//===----------------------------------------------------------------------===//
1683// Data-recursive visitor methods.
1684//===----------------------------------------------------------------------===//
1685
1686namespace {
1687#define DEF_JOB(NAME, DATA, KIND)\
1688class NAME : public VisitorJob {\
1689public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001690 NAME(const DATA *d, CXCursor parent) : \
1691 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001692 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001693 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001694};
1695
1696DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1697DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1698DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1699DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1700DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1701 ExplicitTemplateArgsVisitKind)
1702DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1703DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1704DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1705#undef DEF_JOB
1706
1707class DeclVisit : public VisitorJob {
1708public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001709 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001710 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001711 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001712 static bool classof(const VisitorJob *VJ) {
1713 return VJ->getKind() == DeclVisitKind;
1714 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001715 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001716 bool isFirst() const { return data[1] ? true : false; }
1717};
1718class TypeLocVisit : public VisitorJob {
1719public:
1720 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1721 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1722 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1723
1724 static bool classof(const VisitorJob *VJ) {
1725 return VJ->getKind() == TypeLocVisitKind;
1726 }
1727
1728 TypeLoc get() const {
1729 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001730 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001731 }
1732};
1733
1734class LabelRefVisit : public VisitorJob {
1735public:
1736 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1737 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1738 labelLoc.getPtrEncoding()) {}
1739
1740 static bool classof(const VisitorJob *VJ) {
1741 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1742 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001743 const LabelDecl *get() const {
1744 return static_cast<const LabelDecl *>(data[0]);
1745 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001746 SourceLocation getLoc() const {
1747 return SourceLocation::getFromPtrEncoding(data[1]); }
1748};
1749
1750class NestedNameSpecifierLocVisit : public VisitorJob {
1751public:
1752 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1753 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1754 Qualifier.getNestedNameSpecifier(),
1755 Qualifier.getOpaqueData()) { }
1756
1757 static bool classof(const VisitorJob *VJ) {
1758 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1759 }
1760
1761 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001762 return NestedNameSpecifierLoc(
1763 const_cast<NestedNameSpecifier *>(
1764 static_cast<const NestedNameSpecifier *>(data[0])),
1765 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001766 }
1767};
1768
1769class DeclarationNameInfoVisit : public VisitorJob {
1770public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001771 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001772 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001773 static bool classof(const VisitorJob *VJ) {
1774 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1775 }
1776 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001777 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001778 switch (S->getStmtClass()) {
1779 default:
1780 llvm_unreachable("Unhandled Stmt");
1781 case clang::Stmt::MSDependentExistsStmtClass:
1782 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1783 case Stmt::CXXDependentScopeMemberExprClass:
1784 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1785 case Stmt::DependentScopeDeclRefExprClass:
1786 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1787 }
1788 }
1789};
1790class MemberRefVisit : public VisitorJob {
1791public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001792 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001793 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1794 L.getPtrEncoding()) {}
1795 static bool classof(const VisitorJob *VJ) {
1796 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1797 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001798 const FieldDecl *get() const {
1799 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001800 }
1801 SourceLocation getLoc() const {
1802 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1803 }
1804};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001805class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001806 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001807 VisitorWorkList &WL;
1808 CXCursor Parent;
1809public:
1810 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1811 : WL(wl), Parent(parent) {}
1812
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001813 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1814 void VisitBlockExpr(const BlockExpr *B);
1815 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1816 void VisitCompoundStmt(const CompoundStmt *S);
1817 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1818 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1819 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1820 void VisitCXXNewExpr(const CXXNewExpr *E);
1821 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1822 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1823 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1824 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1825 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1826 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1827 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1828 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1829 void VisitDeclRefExpr(const DeclRefExpr *D);
1830 void VisitDeclStmt(const DeclStmt *S);
1831 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1832 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1833 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1834 void VisitForStmt(const ForStmt *FS);
1835 void VisitGotoStmt(const GotoStmt *GS);
1836 void VisitIfStmt(const IfStmt *If);
1837 void VisitInitListExpr(const InitListExpr *IE);
1838 void VisitMemberExpr(const MemberExpr *M);
1839 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1840 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1841 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1842 void VisitOverloadExpr(const OverloadExpr *E);
1843 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1844 void VisitStmt(const Stmt *S);
1845 void VisitSwitchStmt(const SwitchStmt *S);
1846 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001847 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1848 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1849 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1850 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1851 void VisitVAArgExpr(const VAArgExpr *E);
1852 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1853 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1854 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1855 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001856 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1857 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001858 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001859
Guy Benyei11169dd2012-12-18 14:30:41 +00001860private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001861 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001862 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1863 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001864 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1865 void AddStmt(const Stmt *S);
1866 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001867 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001868 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001869 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001870};
1871} // end anonyous namespace
1872
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001873void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001874 // 'S' should always be non-null, since it comes from the
1875 // statement we are visiting.
1876 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1877}
1878
1879void
1880EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1881 if (Qualifier)
1882 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1883}
1884
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001885void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001886 if (S)
1887 WL.push_back(StmtVisit(S, Parent));
1888}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001889void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001890 if (D)
1891 WL.push_back(DeclVisit(D, Parent, isFirst));
1892}
1893void EnqueueVisitor::
1894 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1895 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001896 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001897}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001898void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001899 if (D)
1900 WL.push_back(MemberRefVisit(D, L, Parent));
1901}
1902void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1903 if (TI)
1904 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1905 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001906void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001907 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001908 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001909 AddStmt(*Child);
1910 }
1911 if (size == WL.size())
1912 return;
1913 // Now reverse the entries we just added. This will match the DFS
1914 // ordering performed by the worklist.
1915 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1916 std::reverse(I, E);
1917}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001918namespace {
1919class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1920 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001921 /// \brief Process clauses with list of variables.
1922 template <typename T>
1923 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001924public:
1925 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1926#define OPENMP_CLAUSE(Name, Class) \
1927 void Visit##Class(const Class *C);
1928#include "clang/Basic/OpenMPKinds.def"
1929};
1930
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001931void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1932 Visitor->AddStmt(C->getCondition());
1933}
1934
Alexey Bataev568a8332014-03-06 06:15:19 +00001935void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1936 Visitor->AddStmt(C->getNumThreads());
1937}
1938
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001939void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001940
1941template<typename T>
1942void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
1943 for (typename T::varlist_const_iterator I = Node->varlist_begin(),
1944 E = Node->varlist_end();
1945 I != E; ++I)
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001946 Visitor->AddStmt(*I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001947}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001948
1949void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001950 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001951}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001952void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1953 const OMPFirstprivateClause *C) {
1954 VisitOMPClauseList(C);
1955}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001956void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001957 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001958}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001959}
Alexey Bataev756c1962013-09-24 03:17:45 +00001960
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001961void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1962 unsigned size = WL.size();
1963 OMPClauseEnqueue Visitor(this);
1964 Visitor.Visit(S);
1965 if (size == WL.size())
1966 return;
1967 // Now reverse the entries we just added. This will match the DFS
1968 // ordering performed by the worklist.
1969 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1970 std::reverse(I, E);
1971}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001972void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001973 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1974}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001975void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001976 AddDecl(B->getBlockDecl());
1977}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001978void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001979 EnqueueChildren(E);
1980 AddTypeLoc(E->getTypeSourceInfo());
1981}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001982void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1983 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001984 E = S->body_rend(); I != E; ++I) {
1985 AddStmt(*I);
1986 }
1987}
1988void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001989VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001990 AddStmt(S->getSubStmt());
1991 AddDeclarationNameInfo(S);
1992 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1993 AddNestedNameSpecifierLoc(QualifierLoc);
1994}
1995
1996void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001997VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001998 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
1999 AddDeclarationNameInfo(E);
2000 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2001 AddNestedNameSpecifierLoc(QualifierLoc);
2002 if (!E->isImplicitAccess())
2003 AddStmt(E->getBase());
2004}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002005void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002006 // Enqueue the initializer , if any.
2007 AddStmt(E->getInitializer());
2008 // Enqueue the array size, if any.
2009 AddStmt(E->getArraySize());
2010 // Enqueue the allocated type.
2011 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2012 // Enqueue the placement arguments.
2013 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2014 AddStmt(E->getPlacementArg(I-1));
2015}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002016void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002017 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2018 AddStmt(CE->getArg(I-1));
2019 AddStmt(CE->getCallee());
2020 AddStmt(CE->getArg(0));
2021}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002022void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2023 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002024 // Visit the name of the type being destroyed.
2025 AddTypeLoc(E->getDestroyedTypeInfo());
2026 // Visit the scope type that looks disturbingly like the nested-name-specifier
2027 // but isn't.
2028 AddTypeLoc(E->getScopeTypeInfo());
2029 // Visit the nested-name-specifier.
2030 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2031 AddNestedNameSpecifierLoc(QualifierLoc);
2032 // Visit base expression.
2033 AddStmt(E->getBase());
2034}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002035void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2036 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002037 AddTypeLoc(E->getTypeSourceInfo());
2038}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002039void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2040 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002041 EnqueueChildren(E);
2042 AddTypeLoc(E->getTypeSourceInfo());
2043}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002044void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002045 EnqueueChildren(E);
2046 if (E->isTypeOperand())
2047 AddTypeLoc(E->getTypeOperandSourceInfo());
2048}
2049
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002050void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2051 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002052 EnqueueChildren(E);
2053 AddTypeLoc(E->getTypeSourceInfo());
2054}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002055void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002056 EnqueueChildren(E);
2057 if (E->isTypeOperand())
2058 AddTypeLoc(E->getTypeOperandSourceInfo());
2059}
2060
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002061void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002062 EnqueueChildren(S);
2063 AddDecl(S->getExceptionDecl());
2064}
2065
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002066void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002067 if (DR->hasExplicitTemplateArgs()) {
2068 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2069 }
2070 WL.push_back(DeclRefExprParts(DR, Parent));
2071}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002072void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2073 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002074 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2075 AddDeclarationNameInfo(E);
2076 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2077}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002078void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002079 unsigned size = WL.size();
2080 bool isFirst = true;
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002081 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00002082 D != DEnd; ++D) {
2083 AddDecl(*D, isFirst);
2084 isFirst = false;
2085 }
2086 if (size == WL.size())
2087 return;
2088 // Now reverse the entries we just added. This will match the DFS
2089 // ordering performed by the worklist.
2090 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2091 std::reverse(I, E);
2092}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002093void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002094 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002095 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002096 D = E->designators_rbegin(), DEnd = E->designators_rend();
2097 D != DEnd; ++D) {
2098 if (D->isFieldDesignator()) {
2099 if (FieldDecl *Field = D->getField())
2100 AddMemberRef(Field, D->getFieldLoc());
2101 continue;
2102 }
2103 if (D->isArrayDesignator()) {
2104 AddStmt(E->getArrayIndex(*D));
2105 continue;
2106 }
2107 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2108 AddStmt(E->getArrayRangeEnd(*D));
2109 AddStmt(E->getArrayRangeStart(*D));
2110 }
2111}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002112void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002113 EnqueueChildren(E);
2114 AddTypeLoc(E->getTypeInfoAsWritten());
2115}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002116void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002117 AddStmt(FS->getBody());
2118 AddStmt(FS->getInc());
2119 AddStmt(FS->getCond());
2120 AddDecl(FS->getConditionVariable());
2121 AddStmt(FS->getInit());
2122}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002123void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002124 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2125}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002126void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002127 AddStmt(If->getElse());
2128 AddStmt(If->getThen());
2129 AddStmt(If->getCond());
2130 AddDecl(If->getConditionVariable());
2131}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002132void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002133 // We care about the syntactic form of the initializer list, only.
2134 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2135 IE = Syntactic;
2136 EnqueueChildren(IE);
2137}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002138void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002139 WL.push_back(MemberExprParts(M, Parent));
2140
2141 // If the base of the member access expression is an implicit 'this', don't
2142 // visit it.
2143 // FIXME: If we ever want to show these implicit accesses, this will be
2144 // unfortunate. However, clang_getCursor() relies on this behavior.
2145 if (!M->isImplicitAccess())
2146 AddStmt(M->getBase());
2147}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002148void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002149 AddTypeLoc(E->getEncodedTypeSourceInfo());
2150}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002151void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002152 EnqueueChildren(M);
2153 AddTypeLoc(M->getClassReceiverTypeInfo());
2154}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002155void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002156 // Visit the components of the offsetof expression.
2157 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2158 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2159 const OffsetOfNode &Node = E->getComponent(I-1);
2160 switch (Node.getKind()) {
2161 case OffsetOfNode::Array:
2162 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2163 break;
2164 case OffsetOfNode::Field:
2165 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2166 break;
2167 case OffsetOfNode::Identifier:
2168 case OffsetOfNode::Base:
2169 continue;
2170 }
2171 }
2172 // Visit the type into which we're computing the offset.
2173 AddTypeLoc(E->getTypeSourceInfo());
2174}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002175void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002176 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2177 WL.push_back(OverloadExprParts(E, Parent));
2178}
2179void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002180 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002181 EnqueueChildren(E);
2182 if (E->isArgumentType())
2183 AddTypeLoc(E->getArgumentTypeInfo());
2184}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002185void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002186 EnqueueChildren(S);
2187}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002188void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002189 AddStmt(S->getBody());
2190 AddStmt(S->getCond());
2191 AddDecl(S->getConditionVariable());
2192}
2193
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002194void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002195 AddStmt(W->getBody());
2196 AddStmt(W->getCond());
2197 AddDecl(W->getConditionVariable());
2198}
2199
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002200void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002201 for (unsigned I = E->getNumArgs(); I > 0; --I)
2202 AddTypeLoc(E->getArg(I-1));
2203}
2204
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002205void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002206 AddTypeLoc(E->getQueriedTypeSourceInfo());
2207}
2208
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002209void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002210 EnqueueChildren(E);
2211}
2212
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002213void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002214 VisitOverloadExpr(U);
2215 if (!U->isImplicitAccess())
2216 AddStmt(U->getBase());
2217}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 AddStmt(E->getSubExpr());
2220 AddTypeLoc(E->getWrittenTypeInfo());
2221}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002222void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002223 WL.push_back(SizeOfPackExprParts(E, Parent));
2224}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002225void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002226 // If the opaque value has a source expression, just transparently
2227 // visit that. This is useful for (e.g.) pseudo-object expressions.
2228 if (Expr *SourceExpr = E->getSourceExpr())
2229 return Visit(SourceExpr);
2230}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002231void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002232 AddStmt(E->getBody());
2233 WL.push_back(LambdaExprParts(E, Parent));
2234}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002235void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002236 // Treat the expression like its syntactic form.
2237 Visit(E->getSyntacticForm());
2238}
2239
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002240void EnqueueVisitor::VisitOMPExecutableDirective(
2241 const OMPExecutableDirective *D) {
2242 EnqueueChildren(D);
2243 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2244 E = D->clauses().end();
2245 I != E; ++I)
2246 EnqueueChildren(*I);
2247}
2248
2249void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2250 VisitOMPExecutableDirective(D);
2251}
2252
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002253void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2254 VisitOMPExecutableDirective(D);
2255}
2256
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002257void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002258 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2259}
2260
2261bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2262 if (RegionOfInterest.isValid()) {
2263 SourceRange Range = getRawCursorExtent(C);
2264 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2265 return false;
2266 }
2267 return true;
2268}
2269
2270bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2271 while (!WL.empty()) {
2272 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002273 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002274
2275 // Set the Parent field, then back to its old value once we're done.
2276 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2277
2278 switch (LI.getKind()) {
2279 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002280 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002281 if (!D)
2282 continue;
2283
2284 // For now, perform default visitation for Decls.
2285 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2286 cast<DeclVisit>(&LI)->isFirst())))
2287 return true;
2288
2289 continue;
2290 }
2291 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2292 const ASTTemplateArgumentListInfo *ArgList =
2293 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2294 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2295 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2296 Arg != ArgEnd; ++Arg) {
2297 if (VisitTemplateArgumentLoc(*Arg))
2298 return true;
2299 }
2300 continue;
2301 }
2302 case VisitorJob::TypeLocVisitKind: {
2303 // Perform default visitation for TypeLocs.
2304 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2305 return true;
2306 continue;
2307 }
2308 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002309 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002310 if (LabelStmt *stmt = LS->getStmt()) {
2311 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2312 TU))) {
2313 return true;
2314 }
2315 }
2316 continue;
2317 }
2318
2319 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2320 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2321 if (VisitNestedNameSpecifierLoc(V->get()))
2322 return true;
2323 continue;
2324 }
2325
2326 case VisitorJob::DeclarationNameInfoVisitKind: {
2327 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2328 ->get()))
2329 return true;
2330 continue;
2331 }
2332 case VisitorJob::MemberRefVisitKind: {
2333 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2334 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2335 return true;
2336 continue;
2337 }
2338 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002339 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002340 if (!S)
2341 continue;
2342
2343 // Update the current cursor.
2344 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2345 if (!IsInRegionOfInterest(Cursor))
2346 continue;
2347 switch (Visitor(Cursor, Parent, ClientData)) {
2348 case CXChildVisit_Break: return true;
2349 case CXChildVisit_Continue: break;
2350 case CXChildVisit_Recurse:
2351 if (PostChildrenVisitor)
2352 WL.push_back(PostChildrenVisit(0, Cursor));
2353 EnqueueWorkList(WL, S);
2354 break;
2355 }
2356 continue;
2357 }
2358 case VisitorJob::MemberExprPartsKind: {
2359 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002360 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002361
2362 // Visit the nested-name-specifier
2363 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2364 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2365 return true;
2366
2367 // Visit the declaration name.
2368 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2369 return true;
2370
2371 // Visit the explicitly-specified template arguments, if any.
2372 if (M->hasExplicitTemplateArgs()) {
2373 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2374 *ArgEnd = Arg + M->getNumTemplateArgs();
2375 Arg != ArgEnd; ++Arg) {
2376 if (VisitTemplateArgumentLoc(*Arg))
2377 return true;
2378 }
2379 }
2380 continue;
2381 }
2382 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002383 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002384 // Visit nested-name-specifier, if present.
2385 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2386 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2387 return true;
2388 // Visit declaration name.
2389 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2390 return true;
2391 continue;
2392 }
2393 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002394 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002395 // Visit the nested-name-specifier.
2396 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2397 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2398 return true;
2399 // Visit the declaration name.
2400 if (VisitDeclarationNameInfo(O->getNameInfo()))
2401 return true;
2402 // Visit the overloaded declaration reference.
2403 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2404 return true;
2405 continue;
2406 }
2407 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002408 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002409 NamedDecl *Pack = E->getPack();
2410 if (isa<TemplateTypeParmDecl>(Pack)) {
2411 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2412 E->getPackLoc(), TU)))
2413 return true;
2414
2415 continue;
2416 }
2417
2418 if (isa<TemplateTemplateParmDecl>(Pack)) {
2419 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2420 E->getPackLoc(), TU)))
2421 return true;
2422
2423 continue;
2424 }
2425
2426 // Non-type template parameter packs and function parameter packs are
2427 // treated like DeclRefExpr cursors.
2428 continue;
2429 }
2430
2431 case VisitorJob::LambdaExprPartsKind: {
2432 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002433 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002434 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2435 CEnd = E->explicit_capture_end();
2436 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002437 // FIXME: Lambda init-captures.
2438 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002440
Guy Benyei11169dd2012-12-18 14:30:41 +00002441 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2442 C->getLocation(),
2443 TU)))
2444 return true;
2445 }
2446
2447 // Visit parameters and return type, if present.
2448 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2449 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2450 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2451 // Visit the whole type.
2452 if (Visit(TL))
2453 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002454 } else if (FunctionProtoTypeLoc Proto =
2455 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002456 if (E->hasExplicitParameters()) {
2457 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002458 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2459 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002460 return true;
2461 } else {
2462 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002463 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002464 return true;
2465 }
2466 }
2467 }
2468 break;
2469 }
2470
2471 case VisitorJob::PostChildrenVisitKind:
2472 if (PostChildrenVisitor(Parent, ClientData))
2473 return true;
2474 break;
2475 }
2476 }
2477 return false;
2478}
2479
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002480bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002481 VisitorWorkList *WL = 0;
2482 if (!WorkListFreeList.empty()) {
2483 WL = WorkListFreeList.back();
2484 WL->clear();
2485 WorkListFreeList.pop_back();
2486 }
2487 else {
2488 WL = new VisitorWorkList();
2489 WorkListCache.push_back(WL);
2490 }
2491 EnqueueWorkList(*WL, S);
2492 bool result = RunVisitorWorkList(*WL);
2493 WorkListFreeList.push_back(WL);
2494 return result;
2495}
2496
2497namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002498typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002499RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2500 const DeclarationNameInfo &NI,
2501 const SourceRange &QLoc,
2502 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2503 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2504 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2505 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2506
2507 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2508
2509 RefNamePieces Pieces;
2510
2511 if (WantQualifier && QLoc.isValid())
2512 Pieces.push_back(QLoc);
2513
2514 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2515 Pieces.push_back(NI.getLoc());
2516
2517 if (WantTemplateArgs && TemplateArgs)
2518 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2519 TemplateArgs->RAngleLoc));
2520
2521 if (Kind == DeclarationName::CXXOperatorName) {
2522 Pieces.push_back(SourceLocation::getFromRawEncoding(
2523 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2524 Pieces.push_back(SourceLocation::getFromRawEncoding(
2525 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2526 }
2527
2528 if (WantSinglePiece) {
2529 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2530 Pieces.clear();
2531 Pieces.push_back(R);
2532 }
2533
2534 return Pieces;
2535}
2536}
2537
2538//===----------------------------------------------------------------------===//
2539// Misc. API hooks.
2540//===----------------------------------------------------------------------===//
2541
2542static llvm::sys::Mutex EnableMultithreadingMutex;
2543static bool EnabledMultithreading;
2544
Chad Rosier05c71aa2013-03-27 18:28:23 +00002545static void fatal_error_handler(void *user_data, const std::string& reason,
2546 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002547 // Write the result out to stderr avoiding errs() because raw_ostreams can
2548 // call report_fatal_error.
2549 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2550 ::abort();
2551}
2552
2553extern "C" {
2554CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2555 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002556 // We use crash recovery to make some of our APIs more reliable, implicitly
2557 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002558 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2559 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002560
2561 // Enable support for multithreading in LLVM.
2562 {
2563 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2564 if (!EnabledMultithreading) {
2565 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2566 llvm::llvm_start_multithreaded();
2567 EnabledMultithreading = true;
2568 }
2569 }
2570
2571 CIndexer *CIdxr = new CIndexer();
2572 if (excludeDeclarationsFromPCH)
2573 CIdxr->setOnlyLocalDecls();
2574 if (displayDiagnostics)
2575 CIdxr->setDisplayDiagnostics();
2576
2577 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2578 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2579 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2580 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2581 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2582 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2583
2584 return CIdxr;
2585}
2586
2587void clang_disposeIndex(CXIndex CIdx) {
2588 if (CIdx)
2589 delete static_cast<CIndexer *>(CIdx);
2590}
2591
2592void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2593 if (CIdx)
2594 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2595}
2596
2597unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2598 if (CIdx)
2599 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2600 return 0;
2601}
2602
2603void clang_toggleCrashRecovery(unsigned isEnabled) {
2604 if (isEnabled)
2605 llvm::CrashRecoveryContext::Enable();
2606 else
2607 llvm::CrashRecoveryContext::Disable();
2608}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002609
Guy Benyei11169dd2012-12-18 14:30:41 +00002610CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2611 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002612 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002613 enum CXErrorCode Result =
2614 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002615 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002616 assert((TU && Result == CXError_Success) ||
2617 (!TU && Result != CXError_Success));
2618 return TU;
2619}
2620
2621enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2622 const char *ast_filename,
2623 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002624 if (out_TU)
2625 *out_TU = NULL;
2626
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002627 if (!CIdx || !ast_filename || !out_TU)
2628 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002629
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002630 LOG_FUNC_SECTION {
2631 *Log << ast_filename;
2632 }
2633
Guy Benyei11169dd2012-12-18 14:30:41 +00002634 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2635 FileSystemOptions FileSystemOpts;
2636
2637 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002638 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002639 CXXIdx->getOnlyLocalDecls(), None,
2640 /*CaptureDiagnostics=*/true,
2641 /*AllowPCHWithCompilerErrors=*/true,
2642 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002643 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2644 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002645}
2646
2647unsigned clang_defaultEditingTranslationUnitOptions() {
2648 return CXTranslationUnit_PrecompiledPreamble |
2649 CXTranslationUnit_CacheCompletionResults;
2650}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002651
Guy Benyei11169dd2012-12-18 14:30:41 +00002652CXTranslationUnit
2653clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2654 const char *source_filename,
2655 int num_command_line_args,
2656 const char * const *command_line_args,
2657 unsigned num_unsaved_files,
2658 struct CXUnsavedFile *unsaved_files) {
2659 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2660 return clang_parseTranslationUnit(CIdx, source_filename,
2661 command_line_args, num_command_line_args,
2662 unsaved_files, num_unsaved_files,
2663 Options);
2664}
2665
2666struct ParseTranslationUnitInfo {
2667 CXIndex CIdx;
2668 const char *source_filename;
2669 const char *const *command_line_args;
2670 int num_command_line_args;
2671 struct CXUnsavedFile *unsaved_files;
2672 unsigned num_unsaved_files;
2673 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002674 CXTranslationUnit *out_TU;
2675 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002676};
2677static void clang_parseTranslationUnit_Impl(void *UserData) {
2678 ParseTranslationUnitInfo *PTUI =
2679 static_cast<ParseTranslationUnitInfo*>(UserData);
2680 CXIndex CIdx = PTUI->CIdx;
2681 const char *source_filename = PTUI->source_filename;
2682 const char * const *command_line_args = PTUI->command_line_args;
2683 int num_command_line_args = PTUI->num_command_line_args;
2684 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2685 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2686 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002687 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002688
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002689 // Set up the initial return values.
2690 if (out_TU)
2691 *out_TU = NULL;
2692 PTUI->result = CXError_Failure;
2693
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002694 // Check arguments.
2695 if (!CIdx || !out_TU ||
2696 (unsaved_files == NULL && num_unsaved_files != 0)) {
2697 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002698 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002699 }
2700
Guy Benyei11169dd2012-12-18 14:30:41 +00002701 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2702
2703 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2704 setThreadBackgroundPriority();
2705
2706 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2707 // FIXME: Add a flag for modules.
2708 TranslationUnitKind TUKind
2709 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002710 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002711 = options & CXTranslationUnit_CacheCompletionResults;
2712 bool IncludeBriefCommentsInCodeCompletion
2713 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2714 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2715 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2716
2717 // Configure the diagnostics.
2718 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002719 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002720
2721 // Recover resources if we crash before exiting this function.
2722 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2723 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2724 DiagCleanup(Diags.getPtr());
2725
Ahmed Charlesb8984322014-03-07 20:03:18 +00002726 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2727 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002728
2729 // Recover resources if we crash before exiting this function.
2730 llvm::CrashRecoveryContextCleanupRegistrar<
2731 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2732
2733 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2734 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2735 const llvm::MemoryBuffer *Buffer
2736 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2737 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2738 Buffer));
2739 }
2740
Ahmed Charlesb8984322014-03-07 20:03:18 +00002741 std::unique_ptr<std::vector<const char *>> Args(
2742 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002743
2744 // Recover resources if we crash before exiting this method.
2745 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2746 ArgsCleanup(Args.get());
2747
2748 // Since the Clang C library is primarily used by batch tools dealing with
2749 // (often very broken) source code, where spell-checking can have a
2750 // significant negative impact on performance (particularly when
2751 // precompiled headers are involved), we disable it by default.
2752 // Only do this if we haven't found a spell-checking-related argument.
2753 bool FoundSpellCheckingArgument = false;
2754 for (int I = 0; I != num_command_line_args; ++I) {
2755 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2756 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2757 FoundSpellCheckingArgument = true;
2758 break;
2759 }
2760 }
2761 if (!FoundSpellCheckingArgument)
2762 Args->push_back("-fno-spell-checking");
2763
2764 Args->insert(Args->end(), command_line_args,
2765 command_line_args + num_command_line_args);
2766
2767 // The 'source_filename' argument is optional. If the caller does not
2768 // specify it then it is assumed that the source file is specified
2769 // in the actual argument list.
2770 // Put the source file after command_line_args otherwise if '-x' flag is
2771 // present it will be unused.
2772 if (source_filename)
2773 Args->push_back(source_filename);
2774
2775 // Do we need the detailed preprocessing record?
2776 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2777 Args->push_back("-Xclang");
2778 Args->push_back("-detailed-preprocessing-record");
2779 }
2780
2781 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002782 std::unique_ptr<ASTUnit> ErrUnit;
2783 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
2784 Args->size() ? &(*Args)[0] : 0
2785 /* vector::data() not portable */,
2786 Args->size() ? (&(*Args)[0] + Args->size()) : 0, Diags,
2787 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2788 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2789 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2790 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2791 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2792 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002793
2794 if (NumErrors != Diags->getClient()->getNumErrors()) {
2795 // Make sure to check that 'Unit' is non-NULL.
2796 if (CXXIdx->getDisplayDiagnostics())
2797 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2798 }
2799
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002800 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2801 PTUI->result = CXError_ASTReadError;
2802 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002803 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002804 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2805 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002806}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002807
2808CXTranslationUnit
2809clang_parseTranslationUnit(CXIndex CIdx,
2810 const char *source_filename,
2811 const char *const *command_line_args,
2812 int num_command_line_args,
2813 struct CXUnsavedFile *unsaved_files,
2814 unsigned num_unsaved_files,
2815 unsigned options) {
2816 CXTranslationUnit TU;
2817 enum CXErrorCode Result = clang_parseTranslationUnit2(
2818 CIdx, source_filename, command_line_args, num_command_line_args,
2819 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002820 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002821 assert((TU && Result == CXError_Success) ||
2822 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002823 return TU;
2824}
2825
2826enum CXErrorCode clang_parseTranslationUnit2(
2827 CXIndex CIdx,
2828 const char *source_filename,
2829 const char *const *command_line_args,
2830 int num_command_line_args,
2831 struct CXUnsavedFile *unsaved_files,
2832 unsigned num_unsaved_files,
2833 unsigned options,
2834 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002835 LOG_FUNC_SECTION {
2836 *Log << source_filename << ": ";
2837 for (int i = 0; i != num_command_line_args; ++i)
2838 *Log << command_line_args[i] << " ";
2839 }
2840
Guy Benyei11169dd2012-12-18 14:30:41 +00002841 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2842 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002843 num_unsaved_files, options, out_TU,
2844 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002845 llvm::CrashRecoveryContext CRC;
2846
2847 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2848 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2849 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2850 fprintf(stderr, " 'command_line_args' : [");
2851 for (int i = 0; i != num_command_line_args; ++i) {
2852 if (i)
2853 fprintf(stderr, ", ");
2854 fprintf(stderr, "'%s'", command_line_args[i]);
2855 }
2856 fprintf(stderr, "],\n");
2857 fprintf(stderr, " 'unsaved_files' : [");
2858 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2859 if (i)
2860 fprintf(stderr, ", ");
2861 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2862 unsaved_files[i].Length);
2863 }
2864 fprintf(stderr, "],\n");
2865 fprintf(stderr, " 'options' : %d,\n", options);
2866 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002867
2868 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002869 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002870 if (CXTranslationUnit *TU = PTUI.out_TU)
2871 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002872 }
2873
2874 return PTUI.result;
2875}
2876
2877unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2878 return CXSaveTranslationUnit_None;
2879}
2880
2881namespace {
2882
2883struct SaveTranslationUnitInfo {
2884 CXTranslationUnit TU;
2885 const char *FileName;
2886 unsigned options;
2887 CXSaveError result;
2888};
2889
2890}
2891
2892static void clang_saveTranslationUnit_Impl(void *UserData) {
2893 SaveTranslationUnitInfo *STUI =
2894 static_cast<SaveTranslationUnitInfo*>(UserData);
2895
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002896 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002897 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2898 setThreadBackgroundPriority();
2899
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002900 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002901 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2902}
2903
2904int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2905 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002906 LOG_FUNC_SECTION {
2907 *Log << TU << ' ' << FileName;
2908 }
2909
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002910 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002911 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002912 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002913 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002914
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002915 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002916 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2917 if (!CXXUnit->hasSema())
2918 return CXSaveError_InvalidTU;
2919
2920 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2921
2922 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2923 getenv("LIBCLANG_NOTHREADS")) {
2924 clang_saveTranslationUnit_Impl(&STUI);
2925
2926 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2927 PrintLibclangResourceUsage(TU);
2928
2929 return STUI.result;
2930 }
2931
2932 // We have an AST that has invalid nodes due to compiler errors.
2933 // Use a crash recovery thread for protection.
2934
2935 llvm::CrashRecoveryContext CRC;
2936
2937 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2938 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2939 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2940 fprintf(stderr, " 'options' : %d,\n", options);
2941 fprintf(stderr, "}\n");
2942
2943 return CXSaveError_Unknown;
2944
2945 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2946 PrintLibclangResourceUsage(TU);
2947 }
2948
2949 return STUI.result;
2950}
2951
2952void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2953 if (CTUnit) {
2954 // If the translation unit has been marked as unsafe to free, just discard
2955 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002956 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2957 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002958 return;
2959
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002960 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002961 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002962 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2963 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002964 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002965 delete CTUnit;
2966 }
2967}
2968
2969unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2970 return CXReparse_None;
2971}
2972
2973struct ReparseTranslationUnitInfo {
2974 CXTranslationUnit TU;
2975 unsigned num_unsaved_files;
2976 struct CXUnsavedFile *unsaved_files;
2977 unsigned options;
2978 int result;
2979};
2980
2981static void clang_reparseTranslationUnit_Impl(void *UserData) {
2982 ReparseTranslationUnitInfo *RTUI =
2983 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002984 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002985
Guy Benyei11169dd2012-12-18 14:30:41 +00002986 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002987 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2988 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2989 unsigned options = RTUI->options;
2990 (void) options;
2991
2992 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002993 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002994 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002995 RTUI->result = CXError_InvalidArguments;
2996 return;
2997 }
2998 if (unsaved_files == NULL && num_unsaved_files != 0) {
2999 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003000 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003001 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003002
3003 // Reset the associated diagnostics.
3004 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3005 TU->Diagnostics = 0;
3006
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003007 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003008 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3009 setThreadBackgroundPriority();
3010
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003011 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003012 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003013
3014 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3015 new std::vector<ASTUnit::RemappedFile>());
3016
Guy Benyei11169dd2012-12-18 14:30:41 +00003017 // Recover resources if we crash before exiting this function.
3018 llvm::CrashRecoveryContextCleanupRegistrar<
3019 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3020
3021 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3022 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3023 const llvm::MemoryBuffer *Buffer
3024 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3025 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3026 Buffer));
3027 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003028
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003029 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003030 RTUI->result = CXError_Success;
3031 else if (isASTReadError(CXXUnit))
3032 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003033}
3034
3035int clang_reparseTranslationUnit(CXTranslationUnit TU,
3036 unsigned num_unsaved_files,
3037 struct CXUnsavedFile *unsaved_files,
3038 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003039 LOG_FUNC_SECTION {
3040 *Log << TU;
3041 }
3042
Guy Benyei11169dd2012-12-18 14:30:41 +00003043 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003044 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003045
3046 if (getenv("LIBCLANG_NOTHREADS")) {
3047 clang_reparseTranslationUnit_Impl(&RTUI);
3048 return RTUI.result;
3049 }
3050
3051 llvm::CrashRecoveryContext CRC;
3052
3053 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3054 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003055 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003056 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003057 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3058 PrintLibclangResourceUsage(TU);
3059
3060 return RTUI.result;
3061}
3062
3063
3064CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003065 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003066 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003067 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003068 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003069
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003070 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003071 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003072}
3073
3074CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003075 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003076 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003077 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003078 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003079
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003080 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003081 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3082}
3083
3084} // end: extern "C"
3085
3086//===----------------------------------------------------------------------===//
3087// CXFile Operations.
3088//===----------------------------------------------------------------------===//
3089
3090extern "C" {
3091CXString clang_getFileName(CXFile SFile) {
3092 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003093 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003094
3095 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003096 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003097}
3098
3099time_t clang_getFileTime(CXFile SFile) {
3100 if (!SFile)
3101 return 0;
3102
3103 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3104 return FEnt->getModificationTime();
3105}
3106
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003107CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003108 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003109 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003110 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003111 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003112
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003113 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003114
3115 FileManager &FMgr = CXXUnit->getFileManager();
3116 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3117}
3118
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003119unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3120 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003121 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003122 LOG_BAD_TU(TU);
3123 return 0;
3124 }
3125
3126 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003127 return 0;
3128
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003129 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003130 FileEntry *FEnt = static_cast<FileEntry *>(file);
3131 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3132 .isFileMultipleIncludeGuarded(FEnt);
3133}
3134
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003135int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3136 if (!file || !outID)
3137 return 1;
3138
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003139 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003140 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3141 outID->data[0] = ID.getDevice();
3142 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003143 outID->data[2] = FEnt->getModificationTime();
3144 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003145}
3146
Guy Benyei11169dd2012-12-18 14:30:41 +00003147} // end: extern "C"
3148
3149//===----------------------------------------------------------------------===//
3150// CXCursor Operations.
3151//===----------------------------------------------------------------------===//
3152
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003153static const Decl *getDeclFromExpr(const Stmt *E) {
3154 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003155 return getDeclFromExpr(CE->getSubExpr());
3156
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003157 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003158 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003159 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003160 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003161 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003162 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003163 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003164 if (PRE->isExplicitProperty())
3165 return PRE->getExplicitProperty();
3166 // It could be messaging both getter and setter as in:
3167 // ++myobj.myprop;
3168 // in which case prefer to associate the setter since it is less obvious
3169 // from inspecting the source that the setter is going to get called.
3170 if (PRE->isMessagingSetter())
3171 return PRE->getImplicitPropertySetter();
3172 return PRE->getImplicitPropertyGetter();
3173 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003174 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003175 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003176 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003177 if (Expr *Src = OVE->getSourceExpr())
3178 return getDeclFromExpr(Src);
3179
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003180 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003181 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003182 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003183 if (!CE->isElidable())
3184 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003185 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003186 return OME->getMethodDecl();
3187
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003188 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003189 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003190 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003191 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3192 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003193 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003194 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3195 isa<ParmVarDecl>(SizeOfPack->getPack()))
3196 return SizeOfPack->getPack();
3197
3198 return 0;
3199}
3200
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003201static SourceLocation getLocationFromExpr(const Expr *E) {
3202 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003203 return getLocationFromExpr(CE->getSubExpr());
3204
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003205 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003206 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003207 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003208 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003209 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003210 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003211 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003212 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003213 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003214 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003215 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003216 return PropRef->getLocation();
3217
3218 return E->getLocStart();
3219}
3220
3221extern "C" {
3222
3223unsigned clang_visitChildren(CXCursor parent,
3224 CXCursorVisitor visitor,
3225 CXClientData client_data) {
3226 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3227 /*VisitPreprocessorLast=*/false);
3228 return CursorVis.VisitChildren(parent);
3229}
3230
3231#ifndef __has_feature
3232#define __has_feature(x) 0
3233#endif
3234#if __has_feature(blocks)
3235typedef enum CXChildVisitResult
3236 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3237
3238static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3239 CXClientData client_data) {
3240 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3241 return block(cursor, parent);
3242}
3243#else
3244// If we are compiled with a compiler that doesn't have native blocks support,
3245// define and call the block manually, so the
3246typedef struct _CXChildVisitResult
3247{
3248 void *isa;
3249 int flags;
3250 int reserved;
3251 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3252 CXCursor);
3253} *CXCursorVisitorBlock;
3254
3255static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3256 CXClientData client_data) {
3257 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3258 return block->invoke(block, cursor, parent);
3259}
3260#endif
3261
3262
3263unsigned clang_visitChildrenWithBlock(CXCursor parent,
3264 CXCursorVisitorBlock block) {
3265 return clang_visitChildren(parent, visitWithBlock, block);
3266}
3267
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003268static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003269 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003270 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003271
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003272 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003273 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003274 if (const ObjCPropertyImplDecl *PropImpl =
3275 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003276 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003277 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003278
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003279 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003280 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003281 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003282
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003283 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003284 }
3285
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003286 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003287 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003288
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003289 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003290 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3291 // and returns different names. NamedDecl returns the class name and
3292 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003293 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003294
3295 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003296 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003297
3298 SmallString<1024> S;
3299 llvm::raw_svector_ostream os(S);
3300 ND->printName(os);
3301
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003302 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003303}
3304
3305CXString clang_getCursorSpelling(CXCursor C) {
3306 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003307 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003308
3309 if (clang_isReference(C.kind)) {
3310 switch (C.kind) {
3311 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003312 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003313 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003314 }
3315 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003316 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003317 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003318 }
3319 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003320 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003321 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003322 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003323 }
3324 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003325 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003326 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003327 }
3328 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003329 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003330 assert(Type && "Missing type decl");
3331
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003332 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003333 getAsString());
3334 }
3335 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003336 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003337 assert(Template && "Missing template decl");
3338
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003339 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003340 }
3341
3342 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003343 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003344 assert(NS && "Missing namespace decl");
3345
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003346 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003347 }
3348
3349 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003350 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003351 assert(Field && "Missing member decl");
3352
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003353 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003354 }
3355
3356 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003357 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003358 assert(Label && "Missing label");
3359
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003360 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003361 }
3362
3363 case CXCursor_OverloadedDeclRef: {
3364 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003365 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3366 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003367 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003368 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003369 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003370 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003371 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003372 OverloadedTemplateStorage *Ovl
3373 = Storage.get<OverloadedTemplateStorage*>();
3374 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003375 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003376 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003377 }
3378
3379 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003380 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003381 assert(Var && "Missing variable decl");
3382
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003383 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 }
3385
3386 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003387 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003388 }
3389 }
3390
3391 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003392 const Expr *E = getCursorExpr(C);
3393
3394 if (C.kind == CXCursor_ObjCStringLiteral ||
3395 C.kind == CXCursor_StringLiteral) {
3396 const StringLiteral *SLit;
3397 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3398 SLit = OSL->getString();
3399 } else {
3400 SLit = cast<StringLiteral>(E);
3401 }
3402 SmallString<256> Buf;
3403 llvm::raw_svector_ostream OS(Buf);
3404 SLit->outputString(OS);
3405 return cxstring::createDup(OS.str());
3406 }
3407
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003408 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003409 if (D)
3410 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003411 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003412 }
3413
3414 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003415 const Stmt *S = getCursorStmt(C);
3416 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003417 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003418
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003419 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003420 }
3421
3422 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003423 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003424 ->getNameStart());
3425
3426 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003427 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003428 ->getNameStart());
3429
3430 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003431 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003432
3433 if (clang_isDeclaration(C.kind))
3434 return getDeclSpelling(getCursorDecl(C));
3435
3436 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003437 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003438 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003439 }
3440
3441 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003442 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003443 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003444 }
3445
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003446 if (C.kind == CXCursor_PackedAttr) {
3447 return cxstring::createRef("packed");
3448 }
3449
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003450 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003451}
3452
3453CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3454 unsigned pieceIndex,
3455 unsigned options) {
3456 if (clang_Cursor_isNull(C))
3457 return clang_getNullRange();
3458
3459 ASTContext &Ctx = getCursorContext(C);
3460
3461 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003462 const Stmt *S = getCursorStmt(C);
3463 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003464 if (pieceIndex > 0)
3465 return clang_getNullRange();
3466 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3467 }
3468
3469 return clang_getNullRange();
3470 }
3471
3472 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003473 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003474 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3475 if (pieceIndex >= ME->getNumSelectorLocs())
3476 return clang_getNullRange();
3477 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3478 }
3479 }
3480
3481 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3482 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003483 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003484 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3485 if (pieceIndex >= MD->getNumSelectorLocs())
3486 return clang_getNullRange();
3487 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3488 }
3489 }
3490
3491 if (C.kind == CXCursor_ObjCCategoryDecl ||
3492 C.kind == CXCursor_ObjCCategoryImplDecl) {
3493 if (pieceIndex > 0)
3494 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003495 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003496 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3497 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003498 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003499 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3500 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3501 }
3502
3503 if (C.kind == CXCursor_ModuleImportDecl) {
3504 if (pieceIndex > 0)
3505 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003506 if (const ImportDecl *ImportD =
3507 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003508 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3509 if (!Locs.empty())
3510 return cxloc::translateSourceRange(Ctx,
3511 SourceRange(Locs.front(), Locs.back()));
3512 }
3513 return clang_getNullRange();
3514 }
3515
3516 // FIXME: A CXCursor_InclusionDirective should give the location of the
3517 // filename, but we don't keep track of this.
3518
3519 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3520 // but we don't keep track of this.
3521
3522 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3523 // but we don't keep track of this.
3524
3525 // Default handling, give the location of the cursor.
3526
3527 if (pieceIndex > 0)
3528 return clang_getNullRange();
3529
3530 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3531 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3532 return cxloc::translateSourceRange(Ctx, Loc);
3533}
3534
3535CXString clang_getCursorDisplayName(CXCursor C) {
3536 if (!clang_isDeclaration(C.kind))
3537 return clang_getCursorSpelling(C);
3538
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003539 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003540 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003541 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003542
3543 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003544 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003545 D = FunTmpl->getTemplatedDecl();
3546
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003547 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003548 SmallString<64> Str;
3549 llvm::raw_svector_ostream OS(Str);
3550 OS << *Function;
3551 if (Function->getPrimaryTemplate())
3552 OS << "<>";
3553 OS << "(";
3554 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3555 if (I)
3556 OS << ", ";
3557 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3558 }
3559
3560 if (Function->isVariadic()) {
3561 if (Function->getNumParams())
3562 OS << ", ";
3563 OS << "...";
3564 }
3565 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003566 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003567 }
3568
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003569 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003570 SmallString<64> Str;
3571 llvm::raw_svector_ostream OS(Str);
3572 OS << *ClassTemplate;
3573 OS << "<";
3574 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3575 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3576 if (I)
3577 OS << ", ";
3578
3579 NamedDecl *Param = Params->getParam(I);
3580 if (Param->getIdentifier()) {
3581 OS << Param->getIdentifier()->getName();
3582 continue;
3583 }
3584
3585 // There is no parameter name, which makes this tricky. Try to come up
3586 // with something useful that isn't too long.
3587 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3588 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3589 else if (NonTypeTemplateParmDecl *NTTP
3590 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3591 OS << NTTP->getType().getAsString(Policy);
3592 else
3593 OS << "template<...> class";
3594 }
3595
3596 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003597 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003598 }
3599
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003600 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003601 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3602 // If the type was explicitly written, use that.
3603 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003604 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003605
Benjamin Kramer9170e912013-02-22 15:46:01 +00003606 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003607 llvm::raw_svector_ostream OS(Str);
3608 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003609 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 ClassSpec->getTemplateArgs().data(),
3611 ClassSpec->getTemplateArgs().size(),
3612 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003613 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003614 }
3615
3616 return clang_getCursorSpelling(C);
3617}
3618
3619CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3620 switch (Kind) {
3621 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003622 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003623 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003624 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003626 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003627 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003628 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003629 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003630 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003631 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003632 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003633 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003634 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003636 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003638 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003639 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003640 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003642 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003643 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003644 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003646 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003648 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003650 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003652 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003654 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003656 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003658 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003660 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003662 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003664 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003666 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003668 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003670 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003672 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003749 case CXCursor_ObjCSelfExpr:
3750 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003761 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003762 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003867 case CXCursor_PackedAttr:
3868 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003879 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003880 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003910 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003914 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003916 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003917 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003918 return cxstring::createRef("OMPParallelDirective");
3919 case CXCursor_OMPSimdDirective:
3920 return cxstring::createRef("OMPSimdDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 }
3922
3923 llvm_unreachable("Unhandled CXCursorKind");
3924}
3925
3926struct GetCursorData {
3927 SourceLocation TokenBeginLoc;
3928 bool PointsAtMacroArgExpansion;
3929 bool VisitedObjCPropertyImplDecl;
3930 SourceLocation VisitedDeclaratorDeclStartLoc;
3931 CXCursor &BestCursor;
3932
3933 GetCursorData(SourceManager &SM,
3934 SourceLocation tokenBegin, CXCursor &outputCursor)
3935 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3936 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3937 VisitedObjCPropertyImplDecl = false;
3938 }
3939};
3940
3941static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3942 CXCursor parent,
3943 CXClientData client_data) {
3944 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3945 CXCursor *BestCursor = &Data->BestCursor;
3946
3947 // If we point inside a macro argument we should provide info of what the
3948 // token is so use the actual cursor, don't replace it with a macro expansion
3949 // cursor.
3950 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3951 return CXChildVisit_Recurse;
3952
3953 if (clang_isDeclaration(cursor.kind)) {
3954 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003955 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003956 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3957 if (MD->isImplicit())
3958 return CXChildVisit_Break;
3959
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003960 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003961 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3962 // Check that when we have multiple @class references in the same line,
3963 // that later ones do not override the previous ones.
3964 // If we have:
3965 // @class Foo, Bar;
3966 // source ranges for both start at '@', so 'Bar' will end up overriding
3967 // 'Foo' even though the cursor location was at 'Foo'.
3968 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3969 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003970 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003971 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3972 if (PrevID != ID &&
3973 !PrevID->isThisDeclarationADefinition() &&
3974 !ID->isThisDeclarationADefinition())
3975 return CXChildVisit_Break;
3976 }
3977
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003978 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003979 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3980 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3981 // Check that when we have multiple declarators in the same line,
3982 // that later ones do not override the previous ones.
3983 // If we have:
3984 // int Foo, Bar;
3985 // source ranges for both start at 'int', so 'Bar' will end up overriding
3986 // 'Foo' even though the cursor location was at 'Foo'.
3987 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3988 return CXChildVisit_Break;
3989 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3990
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003991 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003992 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3993 (void)PropImp;
3994 // Check that when we have multiple @synthesize in the same line,
3995 // that later ones do not override the previous ones.
3996 // If we have:
3997 // @synthesize Foo, Bar;
3998 // source ranges for both start at '@', so 'Bar' will end up overriding
3999 // 'Foo' even though the cursor location was at 'Foo'.
4000 if (Data->VisitedObjCPropertyImplDecl)
4001 return CXChildVisit_Break;
4002 Data->VisitedObjCPropertyImplDecl = true;
4003 }
4004 }
4005
4006 if (clang_isExpression(cursor.kind) &&
4007 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004008 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004009 // Avoid having the cursor of an expression replace the declaration cursor
4010 // when the expression source range overlaps the declaration range.
4011 // This can happen for C++ constructor expressions whose range generally
4012 // include the variable declaration, e.g.:
4013 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4014 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4015 D->getLocation() == Data->TokenBeginLoc)
4016 return CXChildVisit_Break;
4017 }
4018 }
4019
4020 // If our current best cursor is the construction of a temporary object,
4021 // don't replace that cursor with a type reference, because we want
4022 // clang_getCursor() to point at the constructor.
4023 if (clang_isExpression(BestCursor->kind) &&
4024 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4025 cursor.kind == CXCursor_TypeRef) {
4026 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4027 // as having the actual point on the type reference.
4028 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4029 return CXChildVisit_Recurse;
4030 }
4031
4032 *BestCursor = cursor;
4033 return CXChildVisit_Recurse;
4034}
4035
4036CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004037 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004038 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004039 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004040 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004041
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004042 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004043 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4044
4045 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4046 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4047
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004048 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004049 CXFile SearchFile;
4050 unsigned SearchLine, SearchColumn;
4051 CXFile ResultFile;
4052 unsigned ResultLine, ResultColumn;
4053 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4054 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4055 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4056
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004057 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4058 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004059 &ResultColumn, 0);
4060 SearchFileName = clang_getFileName(SearchFile);
4061 ResultFileName = clang_getFileName(ResultFile);
4062 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4063 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004064 *Log << llvm::format("(%s:%d:%d) = %s",
4065 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4066 clang_getCString(KindSpelling))
4067 << llvm::format("(%s:%d:%d):%s%s",
4068 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4069 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004070 clang_disposeString(SearchFileName);
4071 clang_disposeString(ResultFileName);
4072 clang_disposeString(KindSpelling);
4073 clang_disposeString(USR);
4074
4075 CXCursor Definition = clang_getCursorDefinition(Result);
4076 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4077 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4078 CXString DefinitionKindSpelling
4079 = clang_getCursorKindSpelling(Definition.kind);
4080 CXFile DefinitionFile;
4081 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004082 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004083 &DefinitionLine, &DefinitionColumn, 0);
4084 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004085 *Log << llvm::format(" -> %s(%s:%d:%d)",
4086 clang_getCString(DefinitionKindSpelling),
4087 clang_getCString(DefinitionFileName),
4088 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004089 clang_disposeString(DefinitionFileName);
4090 clang_disposeString(DefinitionKindSpelling);
4091 }
4092 }
4093
4094 return Result;
4095}
4096
4097CXCursor clang_getNullCursor(void) {
4098 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4099}
4100
4101unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004102 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4103 // can't set consistently. For example, when visiting a DeclStmt we will set
4104 // it but we don't set it on the result of clang_getCursorDefinition for
4105 // a reference of the same declaration.
4106 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4107 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4108 // to provide that kind of info.
4109 if (clang_isDeclaration(X.kind))
4110 X.data[1] = 0;
4111 if (clang_isDeclaration(Y.kind))
4112 Y.data[1] = 0;
4113
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 return X == Y;
4115}
4116
4117unsigned clang_hashCursor(CXCursor C) {
4118 unsigned Index = 0;
4119 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4120 Index = 1;
4121
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004122 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 std::make_pair(C.kind, C.data[Index]));
4124}
4125
4126unsigned clang_isInvalid(enum CXCursorKind K) {
4127 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4128}
4129
4130unsigned clang_isDeclaration(enum CXCursorKind K) {
4131 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4132 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4133}
4134
4135unsigned clang_isReference(enum CXCursorKind K) {
4136 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4137}
4138
4139unsigned clang_isExpression(enum CXCursorKind K) {
4140 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4141}
4142
4143unsigned clang_isStatement(enum CXCursorKind K) {
4144 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4145}
4146
4147unsigned clang_isAttribute(enum CXCursorKind K) {
4148 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4149}
4150
4151unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4152 return K == CXCursor_TranslationUnit;
4153}
4154
4155unsigned clang_isPreprocessing(enum CXCursorKind K) {
4156 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4157}
4158
4159unsigned clang_isUnexposed(enum CXCursorKind K) {
4160 switch (K) {
4161 case CXCursor_UnexposedDecl:
4162 case CXCursor_UnexposedExpr:
4163 case CXCursor_UnexposedStmt:
4164 case CXCursor_UnexposedAttr:
4165 return true;
4166 default:
4167 return false;
4168 }
4169}
4170
4171CXCursorKind clang_getCursorKind(CXCursor C) {
4172 return C.kind;
4173}
4174
4175CXSourceLocation clang_getCursorLocation(CXCursor C) {
4176 if (clang_isReference(C.kind)) {
4177 switch (C.kind) {
4178 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004179 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004180 = getCursorObjCSuperClassRef(C);
4181 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4182 }
4183
4184 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004185 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004186 = getCursorObjCProtocolRef(C);
4187 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4188 }
4189
4190 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004191 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 = getCursorObjCClassRef(C);
4193 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4194 }
4195
4196 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004197 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4199 }
4200
4201 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004202 std::pair<const TemplateDecl *, SourceLocation> P =
4203 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004204 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4205 }
4206
4207 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004208 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004209 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4210 }
4211
4212 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004213 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004214 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4215 }
4216
4217 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004218 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004219 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4220 }
4221
4222 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004223 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004224 if (!BaseSpec)
4225 return clang_getNullLocation();
4226
4227 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4228 return cxloc::translateSourceLocation(getCursorContext(C),
4229 TSInfo->getTypeLoc().getBeginLoc());
4230
4231 return cxloc::translateSourceLocation(getCursorContext(C),
4232 BaseSpec->getLocStart());
4233 }
4234
4235 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004236 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004237 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4238 }
4239
4240 case CXCursor_OverloadedDeclRef:
4241 return cxloc::translateSourceLocation(getCursorContext(C),
4242 getCursorOverloadedDeclRef(C).second);
4243
4244 default:
4245 // FIXME: Need a way to enumerate all non-reference cases.
4246 llvm_unreachable("Missed a reference kind");
4247 }
4248 }
4249
4250 if (clang_isExpression(C.kind))
4251 return cxloc::translateSourceLocation(getCursorContext(C),
4252 getLocationFromExpr(getCursorExpr(C)));
4253
4254 if (clang_isStatement(C.kind))
4255 return cxloc::translateSourceLocation(getCursorContext(C),
4256 getCursorStmt(C)->getLocStart());
4257
4258 if (C.kind == CXCursor_PreprocessingDirective) {
4259 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4260 return cxloc::translateSourceLocation(getCursorContext(C), L);
4261 }
4262
4263 if (C.kind == CXCursor_MacroExpansion) {
4264 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004265 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004266 return cxloc::translateSourceLocation(getCursorContext(C), L);
4267 }
4268
4269 if (C.kind == CXCursor_MacroDefinition) {
4270 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4271 return cxloc::translateSourceLocation(getCursorContext(C), L);
4272 }
4273
4274 if (C.kind == CXCursor_InclusionDirective) {
4275 SourceLocation L
4276 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4277 return cxloc::translateSourceLocation(getCursorContext(C), L);
4278 }
4279
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004280 if (clang_isAttribute(C.kind)) {
4281 SourceLocation L
4282 = cxcursor::getCursorAttr(C)->getLocation();
4283 return cxloc::translateSourceLocation(getCursorContext(C), L);
4284 }
4285
Guy Benyei11169dd2012-12-18 14:30:41 +00004286 if (!clang_isDeclaration(C.kind))
4287 return clang_getNullLocation();
4288
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004289 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004290 if (!D)
4291 return clang_getNullLocation();
4292
4293 SourceLocation Loc = D->getLocation();
4294 // FIXME: Multiple variables declared in a single declaration
4295 // currently lack the information needed to correctly determine their
4296 // ranges when accounting for the type-specifier. We use context
4297 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4298 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004299 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004300 if (!cxcursor::isFirstInDeclGroup(C))
4301 Loc = VD->getLocation();
4302 }
4303
4304 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004305 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004306 Loc = MD->getSelectorStartLoc();
4307
4308 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4309}
4310
4311} // end extern "C"
4312
4313CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4314 assert(TU);
4315
4316 // Guard against an invalid SourceLocation, or we may assert in one
4317 // of the following calls.
4318 if (SLoc.isInvalid())
4319 return clang_getNullCursor();
4320
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004321 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004322
4323 // Translate the given source location to make it point at the beginning of
4324 // the token under the cursor.
4325 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4326 CXXUnit->getASTContext().getLangOpts());
4327
4328 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4329 if (SLoc.isValid()) {
4330 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4331 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4332 /*VisitPreprocessorLast=*/true,
4333 /*VisitIncludedEntities=*/false,
4334 SourceLocation(SLoc));
4335 CursorVis.visitFileRegion();
4336 }
4337
4338 return Result;
4339}
4340
4341static SourceRange getRawCursorExtent(CXCursor C) {
4342 if (clang_isReference(C.kind)) {
4343 switch (C.kind) {
4344 case CXCursor_ObjCSuperClassRef:
4345 return getCursorObjCSuperClassRef(C).second;
4346
4347 case CXCursor_ObjCProtocolRef:
4348 return getCursorObjCProtocolRef(C).second;
4349
4350 case CXCursor_ObjCClassRef:
4351 return getCursorObjCClassRef(C).second;
4352
4353 case CXCursor_TypeRef:
4354 return getCursorTypeRef(C).second;
4355
4356 case CXCursor_TemplateRef:
4357 return getCursorTemplateRef(C).second;
4358
4359 case CXCursor_NamespaceRef:
4360 return getCursorNamespaceRef(C).second;
4361
4362 case CXCursor_MemberRef:
4363 return getCursorMemberRef(C).second;
4364
4365 case CXCursor_CXXBaseSpecifier:
4366 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4367
4368 case CXCursor_LabelRef:
4369 return getCursorLabelRef(C).second;
4370
4371 case CXCursor_OverloadedDeclRef:
4372 return getCursorOverloadedDeclRef(C).second;
4373
4374 case CXCursor_VariableRef:
4375 return getCursorVariableRef(C).second;
4376
4377 default:
4378 // FIXME: Need a way to enumerate all non-reference cases.
4379 llvm_unreachable("Missed a reference kind");
4380 }
4381 }
4382
4383 if (clang_isExpression(C.kind))
4384 return getCursorExpr(C)->getSourceRange();
4385
4386 if (clang_isStatement(C.kind))
4387 return getCursorStmt(C)->getSourceRange();
4388
4389 if (clang_isAttribute(C.kind))
4390 return getCursorAttr(C)->getRange();
4391
4392 if (C.kind == CXCursor_PreprocessingDirective)
4393 return cxcursor::getCursorPreprocessingDirective(C);
4394
4395 if (C.kind == CXCursor_MacroExpansion) {
4396 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004397 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004398 return TU->mapRangeFromPreamble(Range);
4399 }
4400
4401 if (C.kind == CXCursor_MacroDefinition) {
4402 ASTUnit *TU = getCursorASTUnit(C);
4403 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4404 return TU->mapRangeFromPreamble(Range);
4405 }
4406
4407 if (C.kind == CXCursor_InclusionDirective) {
4408 ASTUnit *TU = getCursorASTUnit(C);
4409 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4410 return TU->mapRangeFromPreamble(Range);
4411 }
4412
4413 if (C.kind == CXCursor_TranslationUnit) {
4414 ASTUnit *TU = getCursorASTUnit(C);
4415 FileID MainID = TU->getSourceManager().getMainFileID();
4416 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4417 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4418 return SourceRange(Start, End);
4419 }
4420
4421 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004422 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004423 if (!D)
4424 return SourceRange();
4425
4426 SourceRange R = D->getSourceRange();
4427 // FIXME: Multiple variables declared in a single declaration
4428 // currently lack the information needed to correctly determine their
4429 // ranges when accounting for the type-specifier. We use context
4430 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4431 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004432 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004433 if (!cxcursor::isFirstInDeclGroup(C))
4434 R.setBegin(VD->getLocation());
4435 }
4436 return R;
4437 }
4438 return SourceRange();
4439}
4440
4441/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4442/// the decl-specifier-seq for declarations.
4443static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4444 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004445 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004446 if (!D)
4447 return SourceRange();
4448
4449 SourceRange R = D->getSourceRange();
4450
4451 // Adjust the start of the location for declarations preceded by
4452 // declaration specifiers.
4453 SourceLocation StartLoc;
4454 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4455 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4456 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004457 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004458 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4459 StartLoc = TI->getTypeLoc().getLocStart();
4460 }
4461
4462 if (StartLoc.isValid() && R.getBegin().isValid() &&
4463 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4464 R.setBegin(StartLoc);
4465
4466 // FIXME: Multiple variables declared in a single declaration
4467 // currently lack the information needed to correctly determine their
4468 // ranges when accounting for the type-specifier. We use context
4469 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4470 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004471 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004472 if (!cxcursor::isFirstInDeclGroup(C))
4473 R.setBegin(VD->getLocation());
4474 }
4475
4476 return R;
4477 }
4478
4479 return getRawCursorExtent(C);
4480}
4481
4482extern "C" {
4483
4484CXSourceRange clang_getCursorExtent(CXCursor C) {
4485 SourceRange R = getRawCursorExtent(C);
4486 if (R.isInvalid())
4487 return clang_getNullRange();
4488
4489 return cxloc::translateSourceRange(getCursorContext(C), R);
4490}
4491
4492CXCursor clang_getCursorReferenced(CXCursor C) {
4493 if (clang_isInvalid(C.kind))
4494 return clang_getNullCursor();
4495
4496 CXTranslationUnit tu = getCursorTU(C);
4497 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004498 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004499 if (!D)
4500 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004501 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004502 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004503 if (const ObjCPropertyImplDecl *PropImpl =
4504 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004505 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4506 return MakeCXCursor(Property, tu);
4507
4508 return C;
4509 }
4510
4511 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004512 const Expr *E = getCursorExpr(C);
4513 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004514 if (D) {
4515 CXCursor declCursor = MakeCXCursor(D, tu);
4516 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4517 declCursor);
4518 return declCursor;
4519 }
4520
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004521 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004522 return MakeCursorOverloadedDeclRef(Ovl, tu);
4523
4524 return clang_getNullCursor();
4525 }
4526
4527 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004528 const Stmt *S = getCursorStmt(C);
4529 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004530 if (LabelDecl *label = Goto->getLabel())
4531 if (LabelStmt *labelS = label->getStmt())
4532 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4533
4534 return clang_getNullCursor();
4535 }
4536
4537 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004538 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004539 return MakeMacroDefinitionCursor(Def, tu);
4540 }
4541
4542 if (!clang_isReference(C.kind))
4543 return clang_getNullCursor();
4544
4545 switch (C.kind) {
4546 case CXCursor_ObjCSuperClassRef:
4547 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4548
4549 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004550 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4551 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004552 return MakeCXCursor(Def, tu);
4553
4554 return MakeCXCursor(Prot, tu);
4555 }
4556
4557 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004558 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4559 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004560 return MakeCXCursor(Def, tu);
4561
4562 return MakeCXCursor(Class, tu);
4563 }
4564
4565 case CXCursor_TypeRef:
4566 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4567
4568 case CXCursor_TemplateRef:
4569 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4570
4571 case CXCursor_NamespaceRef:
4572 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4573
4574 case CXCursor_MemberRef:
4575 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4576
4577 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004578 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004579 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4580 tu ));
4581 }
4582
4583 case CXCursor_LabelRef:
4584 // FIXME: We end up faking the "parent" declaration here because we
4585 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004586 return MakeCXCursor(getCursorLabelRef(C).first,
4587 cxtu::getASTUnit(tu)->getASTContext()
4588 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004589 tu);
4590
4591 case CXCursor_OverloadedDeclRef:
4592 return C;
4593
4594 case CXCursor_VariableRef:
4595 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4596
4597 default:
4598 // We would prefer to enumerate all non-reference cursor kinds here.
4599 llvm_unreachable("Unhandled reference cursor kind");
4600 }
4601}
4602
4603CXCursor clang_getCursorDefinition(CXCursor C) {
4604 if (clang_isInvalid(C.kind))
4605 return clang_getNullCursor();
4606
4607 CXTranslationUnit TU = getCursorTU(C);
4608
4609 bool WasReference = false;
4610 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4611 C = clang_getCursorReferenced(C);
4612 WasReference = true;
4613 }
4614
4615 if (C.kind == CXCursor_MacroExpansion)
4616 return clang_getCursorReferenced(C);
4617
4618 if (!clang_isDeclaration(C.kind))
4619 return clang_getNullCursor();
4620
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004621 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004622 if (!D)
4623 return clang_getNullCursor();
4624
4625 switch (D->getKind()) {
4626 // Declaration kinds that don't really separate the notions of
4627 // declaration and definition.
4628 case Decl::Namespace:
4629 case Decl::Typedef:
4630 case Decl::TypeAlias:
4631 case Decl::TypeAliasTemplate:
4632 case Decl::TemplateTypeParm:
4633 case Decl::EnumConstant:
4634 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004635 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004636 case Decl::IndirectField:
4637 case Decl::ObjCIvar:
4638 case Decl::ObjCAtDefsField:
4639 case Decl::ImplicitParam:
4640 case Decl::ParmVar:
4641 case Decl::NonTypeTemplateParm:
4642 case Decl::TemplateTemplateParm:
4643 case Decl::ObjCCategoryImpl:
4644 case Decl::ObjCImplementation:
4645 case Decl::AccessSpec:
4646 case Decl::LinkageSpec:
4647 case Decl::ObjCPropertyImpl:
4648 case Decl::FileScopeAsm:
4649 case Decl::StaticAssert:
4650 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004651 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004652 case Decl::Label: // FIXME: Is this right??
4653 case Decl::ClassScopeFunctionSpecialization:
4654 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004655 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004656 return C;
4657
4658 // Declaration kinds that don't make any sense here, but are
4659 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004660 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 case Decl::TranslationUnit:
4662 break;
4663
4664 // Declaration kinds for which the definition is not resolvable.
4665 case Decl::UnresolvedUsingTypename:
4666 case Decl::UnresolvedUsingValue:
4667 break;
4668
4669 case Decl::UsingDirective:
4670 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4671 TU);
4672
4673 case Decl::NamespaceAlias:
4674 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4675
4676 case Decl::Enum:
4677 case Decl::Record:
4678 case Decl::CXXRecord:
4679 case Decl::ClassTemplateSpecialization:
4680 case Decl::ClassTemplatePartialSpecialization:
4681 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4682 return MakeCXCursor(Def, TU);
4683 return clang_getNullCursor();
4684
4685 case Decl::Function:
4686 case Decl::CXXMethod:
4687 case Decl::CXXConstructor:
4688 case Decl::CXXDestructor:
4689 case Decl::CXXConversion: {
4690 const FunctionDecl *Def = 0;
4691 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004692 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004693 return clang_getNullCursor();
4694 }
4695
Larisse Voufo39a1e502013-08-06 01:03:05 +00004696 case Decl::Var:
4697 case Decl::VarTemplateSpecialization:
4698 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004699 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004700 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004701 return MakeCXCursor(Def, TU);
4702 return clang_getNullCursor();
4703 }
4704
4705 case Decl::FunctionTemplate: {
4706 const FunctionDecl *Def = 0;
4707 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4708 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4709 return clang_getNullCursor();
4710 }
4711
4712 case Decl::ClassTemplate: {
4713 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4714 ->getDefinition())
4715 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4716 TU);
4717 return clang_getNullCursor();
4718 }
4719
Larisse Voufo39a1e502013-08-06 01:03:05 +00004720 case Decl::VarTemplate: {
4721 if (VarDecl *Def =
4722 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4723 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4724 return clang_getNullCursor();
4725 }
4726
Guy Benyei11169dd2012-12-18 14:30:41 +00004727 case Decl::Using:
4728 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4729 D->getLocation(), TU);
4730
4731 case Decl::UsingShadow:
4732 return clang_getCursorDefinition(
4733 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4734 TU));
4735
4736 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004737 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004738 if (Method->isThisDeclarationADefinition())
4739 return C;
4740
4741 // Dig out the method definition in the associated
4742 // @implementation, if we have it.
4743 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004744 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004745 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4746 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4747 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4748 Method->isInstanceMethod()))
4749 if (Def->isThisDeclarationADefinition())
4750 return MakeCXCursor(Def, TU);
4751
4752 return clang_getNullCursor();
4753 }
4754
4755 case Decl::ObjCCategory:
4756 if (ObjCCategoryImplDecl *Impl
4757 = cast<ObjCCategoryDecl>(D)->getImplementation())
4758 return MakeCXCursor(Impl, TU);
4759 return clang_getNullCursor();
4760
4761 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004762 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004763 return MakeCXCursor(Def, TU);
4764 return clang_getNullCursor();
4765
4766 case Decl::ObjCInterface: {
4767 // There are two notions of a "definition" for an Objective-C
4768 // class: the interface and its implementation. When we resolved a
4769 // reference to an Objective-C class, produce the @interface as
4770 // the definition; when we were provided with the interface,
4771 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004772 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004773 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004774 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004775 return MakeCXCursor(Def, TU);
4776 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4777 return MakeCXCursor(Impl, TU);
4778 return clang_getNullCursor();
4779 }
4780
4781 case Decl::ObjCProperty:
4782 // FIXME: We don't really know where to find the
4783 // ObjCPropertyImplDecls that implement this property.
4784 return clang_getNullCursor();
4785
4786 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004787 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004788 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004789 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004790 return MakeCXCursor(Def, TU);
4791
4792 return clang_getNullCursor();
4793
4794 case Decl::Friend:
4795 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4796 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4797 return clang_getNullCursor();
4798
4799 case Decl::FriendTemplate:
4800 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4801 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4802 return clang_getNullCursor();
4803 }
4804
4805 return clang_getNullCursor();
4806}
4807
4808unsigned clang_isCursorDefinition(CXCursor C) {
4809 if (!clang_isDeclaration(C.kind))
4810 return 0;
4811
4812 return clang_getCursorDefinition(C) == C;
4813}
4814
4815CXCursor clang_getCanonicalCursor(CXCursor C) {
4816 if (!clang_isDeclaration(C.kind))
4817 return C;
4818
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004819 if (const Decl *D = getCursorDecl(C)) {
4820 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004821 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4822 return MakeCXCursor(CatD, getCursorTU(C));
4823
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004824 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4825 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004826 return MakeCXCursor(IFD, getCursorTU(C));
4827
4828 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4829 }
4830
4831 return C;
4832}
4833
4834int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4835 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4836}
4837
4838unsigned clang_getNumOverloadedDecls(CXCursor C) {
4839 if (C.kind != CXCursor_OverloadedDeclRef)
4840 return 0;
4841
4842 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004843 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004844 return E->getNumDecls();
4845
4846 if (OverloadedTemplateStorage *S
4847 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4848 return S->size();
4849
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004850 const Decl *D = Storage.get<const Decl *>();
4851 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004852 return Using->shadow_size();
4853
4854 return 0;
4855}
4856
4857CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4858 if (cursor.kind != CXCursor_OverloadedDeclRef)
4859 return clang_getNullCursor();
4860
4861 if (index >= clang_getNumOverloadedDecls(cursor))
4862 return clang_getNullCursor();
4863
4864 CXTranslationUnit TU = getCursorTU(cursor);
4865 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004866 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004867 return MakeCXCursor(E->decls_begin()[index], TU);
4868
4869 if (OverloadedTemplateStorage *S
4870 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4871 return MakeCXCursor(S->begin()[index], TU);
4872
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004873 const Decl *D = Storage.get<const Decl *>();
4874 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004875 // FIXME: This is, unfortunately, linear time.
4876 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4877 std::advance(Pos, index);
4878 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4879 }
4880
4881 return clang_getNullCursor();
4882}
4883
4884void clang_getDefinitionSpellingAndExtent(CXCursor C,
4885 const char **startBuf,
4886 const char **endBuf,
4887 unsigned *startLine,
4888 unsigned *startColumn,
4889 unsigned *endLine,
4890 unsigned *endColumn) {
4891 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004892 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004893 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4894
4895 SourceManager &SM = FD->getASTContext().getSourceManager();
4896 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4897 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4898 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4899 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4900 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4901 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4902}
4903
4904
4905CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4906 unsigned PieceIndex) {
4907 RefNamePieces Pieces;
4908
4909 switch (C.kind) {
4910 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004911 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004912 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4913 E->getQualifierLoc().getSourceRange());
4914 break;
4915
4916 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004917 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004918 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4919 E->getQualifierLoc().getSourceRange(),
4920 E->getOptionalExplicitTemplateArgs());
4921 break;
4922
4923 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004924 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004925 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004926 const Expr *Callee = OCE->getCallee();
4927 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004928 Callee = ICE->getSubExpr();
4929
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004930 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004931 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4932 DRE->getQualifierLoc().getSourceRange());
4933 }
4934 break;
4935
4936 default:
4937 break;
4938 }
4939
4940 if (Pieces.empty()) {
4941 if (PieceIndex == 0)
4942 return clang_getCursorExtent(C);
4943 } else if (PieceIndex < Pieces.size()) {
4944 SourceRange R = Pieces[PieceIndex];
4945 if (R.isValid())
4946 return cxloc::translateSourceRange(getCursorContext(C), R);
4947 }
4948
4949 return clang_getNullRange();
4950}
4951
4952void clang_enableStackTraces(void) {
4953 llvm::sys::PrintStackTraceOnErrorSignal();
4954}
4955
4956void clang_executeOnThread(void (*fn)(void*), void *user_data,
4957 unsigned stack_size) {
4958 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4959}
4960
4961} // end: extern "C"
4962
4963//===----------------------------------------------------------------------===//
4964// Token-based Operations.
4965//===----------------------------------------------------------------------===//
4966
4967/* CXToken layout:
4968 * int_data[0]: a CXTokenKind
4969 * int_data[1]: starting token location
4970 * int_data[2]: token length
4971 * int_data[3]: reserved
4972 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4973 * otherwise unused.
4974 */
4975extern "C" {
4976
4977CXTokenKind clang_getTokenKind(CXToken CXTok) {
4978 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4979}
4980
4981CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4982 switch (clang_getTokenKind(CXTok)) {
4983 case CXToken_Identifier:
4984 case CXToken_Keyword:
4985 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004986 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004987 ->getNameStart());
4988
4989 case CXToken_Literal: {
4990 // We have stashed the starting pointer in the ptr_data field. Use it.
4991 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004992 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004993 }
4994
4995 case CXToken_Punctuation:
4996 case CXToken_Comment:
4997 break;
4998 }
4999
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005000 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005001 LOG_BAD_TU(TU);
5002 return cxstring::createEmpty();
5003 }
5004
Guy Benyei11169dd2012-12-18 14:30:41 +00005005 // We have to find the starting buffer pointer the hard way, by
5006 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005007 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005008 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005009 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005010
5011 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5012 std::pair<FileID, unsigned> LocInfo
5013 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5014 bool Invalid = false;
5015 StringRef Buffer
5016 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5017 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005018 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005019
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005020 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005021}
5022
5023CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005024 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005025 LOG_BAD_TU(TU);
5026 return clang_getNullLocation();
5027 }
5028
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005029 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005030 if (!CXXUnit)
5031 return clang_getNullLocation();
5032
5033 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5034 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5035}
5036
5037CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005038 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005039 LOG_BAD_TU(TU);
5040 return clang_getNullRange();
5041 }
5042
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005043 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005044 if (!CXXUnit)
5045 return clang_getNullRange();
5046
5047 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5048 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5049}
5050
5051static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5052 SmallVectorImpl<CXToken> &CXTokens) {
5053 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5054 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005055 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005056 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005057 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005058
5059 // Cannot tokenize across files.
5060 if (BeginLocInfo.first != EndLocInfo.first)
5061 return;
5062
5063 // Create a lexer
5064 bool Invalid = false;
5065 StringRef Buffer
5066 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5067 if (Invalid)
5068 return;
5069
5070 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5071 CXXUnit->getASTContext().getLangOpts(),
5072 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5073 Lex.SetCommentRetentionState(true);
5074
5075 // Lex tokens until we hit the end of the range.
5076 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5077 Token Tok;
5078 bool previousWasAt = false;
5079 do {
5080 // Lex the next token
5081 Lex.LexFromRawLexer(Tok);
5082 if (Tok.is(tok::eof))
5083 break;
5084
5085 // Initialize the CXToken.
5086 CXToken CXTok;
5087
5088 // - Common fields
5089 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5090 CXTok.int_data[2] = Tok.getLength();
5091 CXTok.int_data[3] = 0;
5092
5093 // - Kind-specific fields
5094 if (Tok.isLiteral()) {
5095 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005096 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005097 } else if (Tok.is(tok::raw_identifier)) {
5098 // Lookup the identifier to determine whether we have a keyword.
5099 IdentifierInfo *II
5100 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5101
5102 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5103 CXTok.int_data[0] = CXToken_Keyword;
5104 }
5105 else {
5106 CXTok.int_data[0] = Tok.is(tok::identifier)
5107 ? CXToken_Identifier
5108 : CXToken_Keyword;
5109 }
5110 CXTok.ptr_data = II;
5111 } else if (Tok.is(tok::comment)) {
5112 CXTok.int_data[0] = CXToken_Comment;
5113 CXTok.ptr_data = 0;
5114 } else {
5115 CXTok.int_data[0] = CXToken_Punctuation;
5116 CXTok.ptr_data = 0;
5117 }
5118 CXTokens.push_back(CXTok);
5119 previousWasAt = Tok.is(tok::at);
5120 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5121}
5122
5123void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5124 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005125 LOG_FUNC_SECTION {
5126 *Log << TU << ' ' << Range;
5127 }
5128
Guy Benyei11169dd2012-12-18 14:30:41 +00005129 if (Tokens)
5130 *Tokens = 0;
5131 if (NumTokens)
5132 *NumTokens = 0;
5133
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005134 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005135 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005136 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005137 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005138
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005139 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005140 if (!CXXUnit || !Tokens || !NumTokens)
5141 return;
5142
5143 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5144
5145 SourceRange R = cxloc::translateCXSourceRange(Range);
5146 if (R.isInvalid())
5147 return;
5148
5149 SmallVector<CXToken, 32> CXTokens;
5150 getTokens(CXXUnit, R, CXTokens);
5151
5152 if (CXTokens.empty())
5153 return;
5154
5155 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5156 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5157 *NumTokens = CXTokens.size();
5158}
5159
5160void clang_disposeTokens(CXTranslationUnit TU,
5161 CXToken *Tokens, unsigned NumTokens) {
5162 free(Tokens);
5163}
5164
5165} // end: extern "C"
5166
5167//===----------------------------------------------------------------------===//
5168// Token annotation APIs.
5169//===----------------------------------------------------------------------===//
5170
Guy Benyei11169dd2012-12-18 14:30:41 +00005171static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5172 CXCursor parent,
5173 CXClientData client_data);
5174static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5175 CXClientData client_data);
5176
5177namespace {
5178class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005179 CXToken *Tokens;
5180 CXCursor *Cursors;
5181 unsigned NumTokens;
5182 unsigned TokIdx;
5183 unsigned PreprocessingTokIdx;
5184 CursorVisitor AnnotateVis;
5185 SourceManager &SrcMgr;
5186 bool HasContextSensitiveKeywords;
5187
5188 struct PostChildrenInfo {
5189 CXCursor Cursor;
5190 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005191 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005192 unsigned BeforeChildrenTokenIdx;
5193 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005194 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005195
5196 CXToken &getTok(unsigned Idx) {
5197 assert(Idx < NumTokens);
5198 return Tokens[Idx];
5199 }
5200 const CXToken &getTok(unsigned Idx) const {
5201 assert(Idx < NumTokens);
5202 return Tokens[Idx];
5203 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 bool MoreTokens() const { return TokIdx < NumTokens; }
5205 unsigned NextToken() const { return TokIdx; }
5206 void AdvanceToken() { ++TokIdx; }
5207 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005208 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005209 }
5210 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005211 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005212 }
5213 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005214 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005215 }
5216
5217 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005218 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005219 SourceRange);
5220
5221public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005222 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005223 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005224 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005225 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005226 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005227 AnnotateTokensVisitor, this,
5228 /*VisitPreprocessorLast=*/true,
5229 /*VisitIncludedEntities=*/false,
5230 RegionOfInterest,
5231 /*VisitDeclsOnly=*/false,
5232 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005233 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005234 HasContextSensitiveKeywords(false) { }
5235
5236 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5237 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5238 bool postVisitChildren(CXCursor cursor);
5239 void AnnotateTokens();
5240
5241 /// \brief Determine whether the annotator saw any cursors that have
5242 /// context-sensitive keywords.
5243 bool hasContextSensitiveKeywords() const {
5244 return HasContextSensitiveKeywords;
5245 }
5246
5247 ~AnnotateTokensWorker() {
5248 assert(PostChildrenInfos.empty());
5249 }
5250};
5251}
5252
5253void AnnotateTokensWorker::AnnotateTokens() {
5254 // Walk the AST within the region of interest, annotating tokens
5255 // along the way.
5256 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005257}
Guy Benyei11169dd2012-12-18 14:30:41 +00005258
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005259static inline void updateCursorAnnotation(CXCursor &Cursor,
5260 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005261 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005262 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005263 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005264}
5265
5266/// \brief It annotates and advances tokens with a cursor until the comparison
5267//// between the cursor location and the source range is the same as
5268/// \arg compResult.
5269///
5270/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5271/// Pass RangeOverlap to annotate tokens inside a range.
5272void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5273 RangeComparisonResult compResult,
5274 SourceRange range) {
5275 while (MoreTokens()) {
5276 const unsigned I = NextToken();
5277 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005278 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5279 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005280
5281 SourceLocation TokLoc = GetTokenLoc(I);
5282 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005283 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005284 AdvanceToken();
5285 continue;
5286 }
5287 break;
5288 }
5289}
5290
5291/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005292/// \returns true if it advanced beyond all macro tokens, false otherwise.
5293bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005294 CXCursor updateC,
5295 RangeComparisonResult compResult,
5296 SourceRange range) {
5297 assert(MoreTokens());
5298 assert(isFunctionMacroToken(NextToken()) &&
5299 "Should be called only for macro arg tokens");
5300
5301 // This works differently than annotateAndAdvanceTokens; because expanded
5302 // macro arguments can have arbitrary translation-unit source order, we do not
5303 // advance the token index one by one until a token fails the range test.
5304 // We only advance once past all of the macro arg tokens if all of them
5305 // pass the range test. If one of them fails we keep the token index pointing
5306 // at the start of the macro arg tokens so that the failing token will be
5307 // annotated by a subsequent annotation try.
5308
5309 bool atLeastOneCompFail = false;
5310
5311 unsigned I = NextToken();
5312 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5313 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5314 if (TokLoc.isFileID())
5315 continue; // not macro arg token, it's parens or comma.
5316 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5317 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5318 Cursors[I] = updateC;
5319 } else
5320 atLeastOneCompFail = true;
5321 }
5322
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005323 if (atLeastOneCompFail)
5324 return false;
5325
5326 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5327 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005328}
5329
5330enum CXChildVisitResult
5331AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005332 SourceRange cursorRange = getRawCursorExtent(cursor);
5333 if (cursorRange.isInvalid())
5334 return CXChildVisit_Recurse;
5335
5336 if (!HasContextSensitiveKeywords) {
5337 // Objective-C properties can have context-sensitive keywords.
5338 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005339 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005340 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5341 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5342 }
5343 // Objective-C methods can have context-sensitive keywords.
5344 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5345 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005346 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005347 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5348 if (Method->getObjCDeclQualifier())
5349 HasContextSensitiveKeywords = true;
5350 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005351 for (const auto *P : Method->params()) {
5352 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005353 HasContextSensitiveKeywords = true;
5354 break;
5355 }
5356 }
5357 }
5358 }
5359 }
5360 // C++ methods can have context-sensitive keywords.
5361 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005362 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005363 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5364 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5365 HasContextSensitiveKeywords = true;
5366 }
5367 }
5368 // C++ classes can have context-sensitive keywords.
5369 else if (cursor.kind == CXCursor_StructDecl ||
5370 cursor.kind == CXCursor_ClassDecl ||
5371 cursor.kind == CXCursor_ClassTemplate ||
5372 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005373 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005374 if (D->hasAttr<FinalAttr>())
5375 HasContextSensitiveKeywords = true;
5376 }
5377 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005378
5379 // Don't override a property annotation with its getter/setter method.
5380 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5381 parent.kind == CXCursor_ObjCPropertyDecl)
5382 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005383
5384 if (clang_isPreprocessing(cursor.kind)) {
5385 // Items in the preprocessing record are kept separate from items in
5386 // declarations, so we keep a separate token index.
5387 unsigned SavedTokIdx = TokIdx;
5388 TokIdx = PreprocessingTokIdx;
5389
5390 // Skip tokens up until we catch up to the beginning of the preprocessing
5391 // entry.
5392 while (MoreTokens()) {
5393 const unsigned I = NextToken();
5394 SourceLocation TokLoc = GetTokenLoc(I);
5395 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5396 case RangeBefore:
5397 AdvanceToken();
5398 continue;
5399 case RangeAfter:
5400 case RangeOverlap:
5401 break;
5402 }
5403 break;
5404 }
5405
5406 // Look at all of the tokens within this range.
5407 while (MoreTokens()) {
5408 const unsigned I = NextToken();
5409 SourceLocation TokLoc = GetTokenLoc(I);
5410 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5411 case RangeBefore:
5412 llvm_unreachable("Infeasible");
5413 case RangeAfter:
5414 break;
5415 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005416 // For macro expansions, just note where the beginning of the macro
5417 // expansion occurs.
5418 if (cursor.kind == CXCursor_MacroExpansion) {
5419 if (TokLoc == cursorRange.getBegin())
5420 Cursors[I] = cursor;
5421 AdvanceToken();
5422 break;
5423 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005424 // We may have already annotated macro names inside macro definitions.
5425 if (Cursors[I].kind != CXCursor_MacroExpansion)
5426 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005427 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005428 continue;
5429 }
5430 break;
5431 }
5432
5433 // Save the preprocessing token index; restore the non-preprocessing
5434 // token index.
5435 PreprocessingTokIdx = TokIdx;
5436 TokIdx = SavedTokIdx;
5437 return CXChildVisit_Recurse;
5438 }
5439
5440 if (cursorRange.isInvalid())
5441 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005442
5443 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005444 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005445 const enum CXCursorKind K = clang_getCursorKind(parent);
5446 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005447 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5448 // Attributes are annotated out-of-order, skip tokens until we reach it.
5449 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005450 ? clang_getNullCursor() : parent;
5451
5452 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5453
5454 // Avoid having the cursor of an expression "overwrite" the annotation of the
5455 // variable declaration that it belongs to.
5456 // This can happen for C++ constructor expressions whose range generally
5457 // include the variable declaration, e.g.:
5458 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005459 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005460 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005461 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005462 const unsigned I = NextToken();
5463 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5464 E->getLocStart() == D->getLocation() &&
5465 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005466 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005467 AdvanceToken();
5468 }
5469 }
5470 }
5471
5472 // Before recursing into the children keep some state that we are going
5473 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5474 // extra work after the child nodes are visited.
5475 // Note that we don't call VisitChildren here to avoid traversing statements
5476 // code-recursively which can blow the stack.
5477
5478 PostChildrenInfo Info;
5479 Info.Cursor = cursor;
5480 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005481 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005482 Info.BeforeChildrenTokenIdx = NextToken();
5483 PostChildrenInfos.push_back(Info);
5484
5485 return CXChildVisit_Recurse;
5486}
5487
5488bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5489 if (PostChildrenInfos.empty())
5490 return false;
5491 const PostChildrenInfo &Info = PostChildrenInfos.back();
5492 if (!clang_equalCursors(Info.Cursor, cursor))
5493 return false;
5494
5495 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5496 const unsigned AfterChildren = NextToken();
5497 SourceRange cursorRange = Info.CursorRange;
5498
5499 // Scan the tokens that are at the end of the cursor, but are not captured
5500 // but the child cursors.
5501 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5502
5503 // Scan the tokens that are at the beginning of the cursor, but are not
5504 // capture by the child cursors.
5505 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5506 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5507 break;
5508
5509 Cursors[I] = cursor;
5510 }
5511
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005512 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5513 // encountered the attribute cursor.
5514 if (clang_isAttribute(cursor.kind))
5515 TokIdx = Info.BeforeReachingCursorIdx;
5516
Guy Benyei11169dd2012-12-18 14:30:41 +00005517 PostChildrenInfos.pop_back();
5518 return false;
5519}
5520
5521static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5522 CXCursor parent,
5523 CXClientData client_data) {
5524 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5525}
5526
5527static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5528 CXClientData client_data) {
5529 return static_cast<AnnotateTokensWorker*>(client_data)->
5530 postVisitChildren(cursor);
5531}
5532
5533namespace {
5534
5535/// \brief Uses the macro expansions in the preprocessing record to find
5536/// and mark tokens that are macro arguments. This info is used by the
5537/// AnnotateTokensWorker.
5538class MarkMacroArgTokensVisitor {
5539 SourceManager &SM;
5540 CXToken *Tokens;
5541 unsigned NumTokens;
5542 unsigned CurIdx;
5543
5544public:
5545 MarkMacroArgTokensVisitor(SourceManager &SM,
5546 CXToken *tokens, unsigned numTokens)
5547 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5548
5549 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5550 if (cursor.kind != CXCursor_MacroExpansion)
5551 return CXChildVisit_Continue;
5552
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005553 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005554 if (macroRange.getBegin() == macroRange.getEnd())
5555 return CXChildVisit_Continue; // it's not a function macro.
5556
5557 for (; CurIdx < NumTokens; ++CurIdx) {
5558 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5559 macroRange.getBegin()))
5560 break;
5561 }
5562
5563 if (CurIdx == NumTokens)
5564 return CXChildVisit_Break;
5565
5566 for (; CurIdx < NumTokens; ++CurIdx) {
5567 SourceLocation tokLoc = getTokenLoc(CurIdx);
5568 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5569 break;
5570
5571 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5572 }
5573
5574 if (CurIdx == NumTokens)
5575 return CXChildVisit_Break;
5576
5577 return CXChildVisit_Continue;
5578 }
5579
5580private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005581 CXToken &getTok(unsigned Idx) {
5582 assert(Idx < NumTokens);
5583 return Tokens[Idx];
5584 }
5585 const CXToken &getTok(unsigned Idx) const {
5586 assert(Idx < NumTokens);
5587 return Tokens[Idx];
5588 }
5589
Guy Benyei11169dd2012-12-18 14:30:41 +00005590 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005591 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005592 }
5593
5594 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5595 // The third field is reserved and currently not used. Use it here
5596 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005597 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005598 }
5599};
5600
5601} // end anonymous namespace
5602
5603static CXChildVisitResult
5604MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5605 CXClientData client_data) {
5606 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5607 parent);
5608}
5609
5610namespace {
5611 struct clang_annotateTokens_Data {
5612 CXTranslationUnit TU;
5613 ASTUnit *CXXUnit;
5614 CXToken *Tokens;
5615 unsigned NumTokens;
5616 CXCursor *Cursors;
5617 };
5618}
5619
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005620/// \brief Used by \c annotatePreprocessorTokens.
5621/// \returns true if lexing was finished, false otherwise.
5622static bool lexNext(Lexer &Lex, Token &Tok,
5623 unsigned &NextIdx, unsigned NumTokens) {
5624 if (NextIdx >= NumTokens)
5625 return true;
5626
5627 ++NextIdx;
5628 Lex.LexFromRawLexer(Tok);
5629 if (Tok.is(tok::eof))
5630 return true;
5631
5632 return false;
5633}
5634
Guy Benyei11169dd2012-12-18 14:30:41 +00005635static void annotatePreprocessorTokens(CXTranslationUnit TU,
5636 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005637 CXCursor *Cursors,
5638 CXToken *Tokens,
5639 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005640 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005641
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005642 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005643 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5644 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005645 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005646 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005647 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005648
5649 if (BeginLocInfo.first != EndLocInfo.first)
5650 return;
5651
5652 StringRef Buffer;
5653 bool Invalid = false;
5654 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5655 if (Buffer.empty() || Invalid)
5656 return;
5657
5658 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5659 CXXUnit->getASTContext().getLangOpts(),
5660 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5661 Buffer.end());
5662 Lex.SetCommentRetentionState(true);
5663
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005664 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005665 // Lex tokens in raw mode until we hit the end of the range, to avoid
5666 // entering #includes or expanding macros.
5667 while (true) {
5668 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005669 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5670 break;
5671 unsigned TokIdx = NextIdx-1;
5672 assert(Tok.getLocation() ==
5673 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005674
5675 reprocess:
5676 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005677 // We have found a preprocessing directive. Annotate the tokens
5678 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005679 //
5680 // FIXME: Some simple tests here could identify macro definitions and
5681 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005682
5683 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005684 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5685 break;
5686
5687 MacroInfo *MI = 0;
5688 if (Tok.is(tok::raw_identifier) &&
5689 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5690 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5691 break;
5692
5693 if (Tok.is(tok::raw_identifier)) {
5694 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5695 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5696 SourceLocation MappedTokLoc =
5697 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5698 MI = getMacroInfo(II, MappedTokLoc, TU);
5699 }
5700 }
5701
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005702 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005703 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005704 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5705 finished = true;
5706 break;
5707 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005708 // If we are in a macro definition, check if the token was ever a
5709 // macro name and annotate it if that's the case.
5710 if (MI) {
5711 SourceLocation SaveLoc = Tok.getLocation();
5712 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5713 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5714 Tok.setLocation(SaveLoc);
5715 if (MacroDef)
5716 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5717 Tok.getLocation(), TU);
5718 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005719 } while (!Tok.isAtStartOfLine());
5720
5721 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5722 assert(TokIdx <= LastIdx);
5723 SourceLocation EndLoc =
5724 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5725 CXCursor Cursor =
5726 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5727
5728 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005729 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005730
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005731 if (finished)
5732 break;
5733 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005734 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005735 }
5736}
5737
5738// This gets run a separate thread to avoid stack blowout.
5739static void clang_annotateTokensImpl(void *UserData) {
5740 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5741 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5742 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5743 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5744 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5745
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005746 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005747 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5748 setThreadBackgroundPriority();
5749
5750 // Determine the region of interest, which contains all of the tokens.
5751 SourceRange RegionOfInterest;
5752 RegionOfInterest.setBegin(
5753 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5754 RegionOfInterest.setEnd(
5755 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5756 Tokens[NumTokens-1])));
5757
Guy Benyei11169dd2012-12-18 14:30:41 +00005758 // Relex the tokens within the source range to look for preprocessing
5759 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005760 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005761
5762 // If begin location points inside a macro argument, set it to the expansion
5763 // location so we can have the full context when annotating semantically.
5764 {
5765 SourceManager &SM = CXXUnit->getSourceManager();
5766 SourceLocation Loc =
5767 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5768 if (Loc.isMacroID())
5769 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5770 }
5771
Guy Benyei11169dd2012-12-18 14:30:41 +00005772 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5773 // Search and mark tokens that are macro argument expansions.
5774 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5775 Tokens, NumTokens);
5776 CursorVisitor MacroArgMarker(TU,
5777 MarkMacroArgTokensVisitorDelegate, &Visitor,
5778 /*VisitPreprocessorLast=*/true,
5779 /*VisitIncludedEntities=*/false,
5780 RegionOfInterest);
5781 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5782 }
5783
5784 // Annotate all of the source locations in the region of interest that map to
5785 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005786 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005787
5788 // FIXME: We use a ridiculous stack size here because the data-recursion
5789 // algorithm uses a large stack frame than the non-data recursive version,
5790 // and AnnotationTokensWorker currently transforms the data-recursion
5791 // algorithm back into a traditional recursion by explicitly calling
5792 // VisitChildren(). We will need to remove this explicit recursive call.
5793 W.AnnotateTokens();
5794
5795 // If we ran into any entities that involve context-sensitive keywords,
5796 // take another pass through the tokens to mark them as such.
5797 if (W.hasContextSensitiveKeywords()) {
5798 for (unsigned I = 0; I != NumTokens; ++I) {
5799 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5800 continue;
5801
5802 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5803 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005804 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005805 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5806 if (Property->getPropertyAttributesAsWritten() != 0 &&
5807 llvm::StringSwitch<bool>(II->getName())
5808 .Case("readonly", true)
5809 .Case("assign", true)
5810 .Case("unsafe_unretained", true)
5811 .Case("readwrite", true)
5812 .Case("retain", true)
5813 .Case("copy", true)
5814 .Case("nonatomic", true)
5815 .Case("atomic", true)
5816 .Case("getter", true)
5817 .Case("setter", true)
5818 .Case("strong", true)
5819 .Case("weak", true)
5820 .Default(false))
5821 Tokens[I].int_data[0] = CXToken_Keyword;
5822 }
5823 continue;
5824 }
5825
5826 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5827 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5828 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5829 if (llvm::StringSwitch<bool>(II->getName())
5830 .Case("in", true)
5831 .Case("out", true)
5832 .Case("inout", true)
5833 .Case("oneway", true)
5834 .Case("bycopy", true)
5835 .Case("byref", true)
5836 .Default(false))
5837 Tokens[I].int_data[0] = CXToken_Keyword;
5838 continue;
5839 }
5840
5841 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5842 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5843 Tokens[I].int_data[0] = CXToken_Keyword;
5844 continue;
5845 }
5846 }
5847 }
5848}
5849
5850extern "C" {
5851
5852void clang_annotateTokens(CXTranslationUnit TU,
5853 CXToken *Tokens, unsigned NumTokens,
5854 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005855 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005856 LOG_BAD_TU(TU);
5857 return;
5858 }
5859 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005860 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005861 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005862 }
5863
5864 LOG_FUNC_SECTION {
5865 *Log << TU << ' ';
5866 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5867 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5868 *Log << clang_getRange(bloc, eloc);
5869 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005870
5871 // Any token we don't specifically annotate will have a NULL cursor.
5872 CXCursor C = clang_getNullCursor();
5873 for (unsigned I = 0; I != NumTokens; ++I)
5874 Cursors[I] = C;
5875
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005876 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005877 if (!CXXUnit)
5878 return;
5879
5880 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5881
5882 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5883 llvm::CrashRecoveryContext CRC;
5884 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5885 GetSafetyThreadStackSize() * 2)) {
5886 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5887 }
5888}
5889
5890} // end: extern "C"
5891
5892//===----------------------------------------------------------------------===//
5893// Operations for querying linkage of a cursor.
5894//===----------------------------------------------------------------------===//
5895
5896extern "C" {
5897CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5898 if (!clang_isDeclaration(cursor.kind))
5899 return CXLinkage_Invalid;
5900
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005901 const Decl *D = cxcursor::getCursorDecl(cursor);
5902 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005903 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005904 case NoLinkage:
5905 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005906 case InternalLinkage: return CXLinkage_Internal;
5907 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5908 case ExternalLinkage: return CXLinkage_External;
5909 };
5910
5911 return CXLinkage_Invalid;
5912}
5913} // end: extern "C"
5914
5915//===----------------------------------------------------------------------===//
5916// Operations for querying language of a cursor.
5917//===----------------------------------------------------------------------===//
5918
5919static CXLanguageKind getDeclLanguage(const Decl *D) {
5920 if (!D)
5921 return CXLanguage_C;
5922
5923 switch (D->getKind()) {
5924 default:
5925 break;
5926 case Decl::ImplicitParam:
5927 case Decl::ObjCAtDefsField:
5928 case Decl::ObjCCategory:
5929 case Decl::ObjCCategoryImpl:
5930 case Decl::ObjCCompatibleAlias:
5931 case Decl::ObjCImplementation:
5932 case Decl::ObjCInterface:
5933 case Decl::ObjCIvar:
5934 case Decl::ObjCMethod:
5935 case Decl::ObjCProperty:
5936 case Decl::ObjCPropertyImpl:
5937 case Decl::ObjCProtocol:
5938 return CXLanguage_ObjC;
5939 case Decl::CXXConstructor:
5940 case Decl::CXXConversion:
5941 case Decl::CXXDestructor:
5942 case Decl::CXXMethod:
5943 case Decl::CXXRecord:
5944 case Decl::ClassTemplate:
5945 case Decl::ClassTemplatePartialSpecialization:
5946 case Decl::ClassTemplateSpecialization:
5947 case Decl::Friend:
5948 case Decl::FriendTemplate:
5949 case Decl::FunctionTemplate:
5950 case Decl::LinkageSpec:
5951 case Decl::Namespace:
5952 case Decl::NamespaceAlias:
5953 case Decl::NonTypeTemplateParm:
5954 case Decl::StaticAssert:
5955 case Decl::TemplateTemplateParm:
5956 case Decl::TemplateTypeParm:
5957 case Decl::UnresolvedUsingTypename:
5958 case Decl::UnresolvedUsingValue:
5959 case Decl::Using:
5960 case Decl::UsingDirective:
5961 case Decl::UsingShadow:
5962 return CXLanguage_CPlusPlus;
5963 }
5964
5965 return CXLanguage_C;
5966}
5967
5968extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005969
5970static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5971 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5972 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005973
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005974 switch (D->getAvailability()) {
5975 case AR_Available:
5976 case AR_NotYetIntroduced:
5977 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005978 return getCursorAvailabilityForDecl(
5979 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005980 return CXAvailability_Available;
5981
5982 case AR_Deprecated:
5983 return CXAvailability_Deprecated;
5984
5985 case AR_Unavailable:
5986 return CXAvailability_NotAvailable;
5987 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005988
5989 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005990}
5991
Guy Benyei11169dd2012-12-18 14:30:41 +00005992enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5993 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005994 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5995 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005996
5997 return CXAvailability_Available;
5998}
5999
6000static CXVersion convertVersion(VersionTuple In) {
6001 CXVersion Out = { -1, -1, -1 };
6002 if (In.empty())
6003 return Out;
6004
6005 Out.Major = In.getMajor();
6006
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006007 Optional<unsigned> Minor = In.getMinor();
6008 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006009 Out.Minor = *Minor;
6010 else
6011 return Out;
6012
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006013 Optional<unsigned> Subminor = In.getSubminor();
6014 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006015 Out.Subminor = *Subminor;
6016
6017 return Out;
6018}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006019
6020static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6021 int *always_deprecated,
6022 CXString *deprecated_message,
6023 int *always_unavailable,
6024 CXString *unavailable_message,
6025 CXPlatformAvailability *availability,
6026 int availability_size) {
6027 bool HadAvailAttr = false;
6028 int N = 0;
Aaron Ballman7dce1a82014-03-07 13:13:38 +00006029 for (Decl::attr_iterator A = D->attr_begin(), AEnd = D->attr_end(); A != AEnd;
6030 ++A) {
6031 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(*A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006032 HadAvailAttr = true;
6033 if (always_deprecated)
6034 *always_deprecated = 1;
6035 if (deprecated_message)
6036 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
6037 continue;
6038 }
6039
Aaron Ballman7dce1a82014-03-07 13:13:38 +00006040 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(*A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006041 HadAvailAttr = true;
6042 if (always_unavailable)
6043 *always_unavailable = 1;
6044 if (unavailable_message) {
6045 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6046 }
6047 continue;
6048 }
6049
Aaron Ballman7dce1a82014-03-07 13:13:38 +00006050 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(*A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006051 HadAvailAttr = true;
6052 if (N < availability_size) {
6053 availability[N].Platform
6054 = cxstring::createDup(Avail->getPlatform()->getName());
6055 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6056 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6057 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6058 availability[N].Unavailable = Avail->getUnavailable();
6059 availability[N].Message = cxstring::createDup(Avail->getMessage());
6060 }
6061 ++N;
6062 }
6063 }
6064
6065 if (!HadAvailAttr)
6066 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6067 return getCursorPlatformAvailabilityForDecl(
6068 cast<Decl>(EnumConst->getDeclContext()),
6069 always_deprecated,
6070 deprecated_message,
6071 always_unavailable,
6072 unavailable_message,
6073 availability,
6074 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006075
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006076 return N;
6077}
6078
Guy Benyei11169dd2012-12-18 14:30:41 +00006079int clang_getCursorPlatformAvailability(CXCursor cursor,
6080 int *always_deprecated,
6081 CXString *deprecated_message,
6082 int *always_unavailable,
6083 CXString *unavailable_message,
6084 CXPlatformAvailability *availability,
6085 int availability_size) {
6086 if (always_deprecated)
6087 *always_deprecated = 0;
6088 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006089 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006090 if (always_unavailable)
6091 *always_unavailable = 0;
6092 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006093 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006094
Guy Benyei11169dd2012-12-18 14:30:41 +00006095 if (!clang_isDeclaration(cursor.kind))
6096 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006097
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006098 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006099 if (!D)
6100 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006101
6102 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6103 deprecated_message,
6104 always_unavailable,
6105 unavailable_message,
6106 availability,
6107 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006108}
6109
6110void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6111 clang_disposeString(availability->Platform);
6112 clang_disposeString(availability->Message);
6113}
6114
6115CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6116 if (clang_isDeclaration(cursor.kind))
6117 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6118
6119 return CXLanguage_Invalid;
6120}
6121
6122 /// \brief If the given cursor is the "templated" declaration
6123 /// descibing a class or function template, return the class or
6124 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006125static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006126 if (!D)
6127 return 0;
6128
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006129 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006130 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6131 return FunTmpl;
6132
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006133 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006134 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6135 return ClassTmpl;
6136
6137 return D;
6138}
6139
6140CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6141 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006142 if (const Decl *D = getCursorDecl(cursor)) {
6143 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006144 if (!DC)
6145 return clang_getNullCursor();
6146
6147 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6148 getCursorTU(cursor));
6149 }
6150 }
6151
6152 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006153 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006154 return MakeCXCursor(D, getCursorTU(cursor));
6155 }
6156
6157 return clang_getNullCursor();
6158}
6159
6160CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6161 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006162 if (const Decl *D = getCursorDecl(cursor)) {
6163 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006164 if (!DC)
6165 return clang_getNullCursor();
6166
6167 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6168 getCursorTU(cursor));
6169 }
6170 }
6171
6172 // FIXME: Note that we can't easily compute the lexical context of a
6173 // statement or expression, so we return nothing.
6174 return clang_getNullCursor();
6175}
6176
6177CXFile clang_getIncludedFile(CXCursor cursor) {
6178 if (cursor.kind != CXCursor_InclusionDirective)
6179 return 0;
6180
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006181 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006182 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006183}
6184
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006185unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6186 if (C.kind != CXCursor_ObjCPropertyDecl)
6187 return CXObjCPropertyAttr_noattr;
6188
6189 unsigned Result = CXObjCPropertyAttr_noattr;
6190 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6191 ObjCPropertyDecl::PropertyAttributeKind Attr =
6192 PD->getPropertyAttributesAsWritten();
6193
6194#define SET_CXOBJCPROP_ATTR(A) \
6195 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6196 Result |= CXObjCPropertyAttr_##A
6197 SET_CXOBJCPROP_ATTR(readonly);
6198 SET_CXOBJCPROP_ATTR(getter);
6199 SET_CXOBJCPROP_ATTR(assign);
6200 SET_CXOBJCPROP_ATTR(readwrite);
6201 SET_CXOBJCPROP_ATTR(retain);
6202 SET_CXOBJCPROP_ATTR(copy);
6203 SET_CXOBJCPROP_ATTR(nonatomic);
6204 SET_CXOBJCPROP_ATTR(setter);
6205 SET_CXOBJCPROP_ATTR(atomic);
6206 SET_CXOBJCPROP_ATTR(weak);
6207 SET_CXOBJCPROP_ATTR(strong);
6208 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6209#undef SET_CXOBJCPROP_ATTR
6210
6211 return Result;
6212}
6213
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006214unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6215 if (!clang_isDeclaration(C.kind))
6216 return CXObjCDeclQualifier_None;
6217
6218 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6219 const Decl *D = getCursorDecl(C);
6220 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6221 QT = MD->getObjCDeclQualifier();
6222 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6223 QT = PD->getObjCDeclQualifier();
6224 if (QT == Decl::OBJC_TQ_None)
6225 return CXObjCDeclQualifier_None;
6226
6227 unsigned Result = CXObjCDeclQualifier_None;
6228 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6229 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6230 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6231 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6232 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6233 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6234
6235 return Result;
6236}
6237
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006238unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6239 if (!clang_isDeclaration(C.kind))
6240 return 0;
6241
6242 const Decl *D = getCursorDecl(C);
6243 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6244 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6245 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6246 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6247
6248 return 0;
6249}
6250
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006251unsigned clang_Cursor_isVariadic(CXCursor C) {
6252 if (!clang_isDeclaration(C.kind))
6253 return 0;
6254
6255 const Decl *D = getCursorDecl(C);
6256 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6257 return FD->isVariadic();
6258 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6259 return MD->isVariadic();
6260
6261 return 0;
6262}
6263
Guy Benyei11169dd2012-12-18 14:30:41 +00006264CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6265 if (!clang_isDeclaration(C.kind))
6266 return clang_getNullRange();
6267
6268 const Decl *D = getCursorDecl(C);
6269 ASTContext &Context = getCursorContext(C);
6270 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6271 if (!RC)
6272 return clang_getNullRange();
6273
6274 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6275}
6276
6277CXString clang_Cursor_getRawCommentText(CXCursor C) {
6278 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006279 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006280
6281 const Decl *D = getCursorDecl(C);
6282 ASTContext &Context = getCursorContext(C);
6283 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6284 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6285 StringRef();
6286
6287 // Don't duplicate the string because RawText points directly into source
6288 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006289 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006290}
6291
6292CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6293 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006294 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006295
6296 const Decl *D = getCursorDecl(C);
6297 const ASTContext &Context = getCursorContext(C);
6298 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6299
6300 if (RC) {
6301 StringRef BriefText = RC->getBriefText(Context);
6302
6303 // Don't duplicate the string because RawComment ensures that this memory
6304 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006305 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006306 }
6307
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006308 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006309}
6310
6311CXComment clang_Cursor_getParsedComment(CXCursor C) {
6312 if (!clang_isDeclaration(C.kind))
6313 return cxcomment::createCXComment(NULL, NULL);
6314
6315 const Decl *D = getCursorDecl(C);
6316 const ASTContext &Context = getCursorContext(C);
6317 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6318
6319 return cxcomment::createCXComment(FC, getCursorTU(C));
6320}
6321
6322CXModule clang_Cursor_getModule(CXCursor C) {
6323 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006324 if (const ImportDecl *ImportD =
6325 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006326 return ImportD->getImportedModule();
6327 }
6328
6329 return 0;
6330}
6331
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006332CXFile clang_Module_getASTFile(CXModule CXMod) {
6333 if (!CXMod)
6334 return 0;
6335 Module *Mod = static_cast<Module*>(CXMod);
6336 return const_cast<FileEntry *>(Mod->getASTFile());
6337}
6338
Guy Benyei11169dd2012-12-18 14:30:41 +00006339CXModule clang_Module_getParent(CXModule CXMod) {
6340 if (!CXMod)
6341 return 0;
6342 Module *Mod = static_cast<Module*>(CXMod);
6343 return Mod->Parent;
6344}
6345
6346CXString clang_Module_getName(CXModule CXMod) {
6347 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006348 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006349 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006350 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006351}
6352
6353CXString clang_Module_getFullName(CXModule CXMod) {
6354 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006355 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006356 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006357 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006358}
6359
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006360unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6361 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006362 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006363 LOG_BAD_TU(TU);
6364 return 0;
6365 }
6366 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006367 return 0;
6368 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006369 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6370 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6371 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006372}
6373
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006374CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6375 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006376 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006377 LOG_BAD_TU(TU);
6378 return 0;
6379 }
6380 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006381 return 0;
6382 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006383 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006384
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006385 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6386 if (Index < TopHeaders.size())
6387 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006388
6389 return 0;
6390}
6391
6392} // end: extern "C"
6393
6394//===----------------------------------------------------------------------===//
6395// C++ AST instrospection.
6396//===----------------------------------------------------------------------===//
6397
6398extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006399unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6400 if (!clang_isDeclaration(C.kind))
6401 return 0;
6402
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006403 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006404 const CXXMethodDecl *Method =
6405 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006406 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6407}
6408
Guy Benyei11169dd2012-12-18 14:30:41 +00006409unsigned clang_CXXMethod_isStatic(CXCursor C) {
6410 if (!clang_isDeclaration(C.kind))
6411 return 0;
6412
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006413 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006414 const CXXMethodDecl *Method =
6415 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006416 return (Method && Method->isStatic()) ? 1 : 0;
6417}
6418
6419unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6420 if (!clang_isDeclaration(C.kind))
6421 return 0;
6422
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006423 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006424 const CXXMethodDecl *Method =
6425 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006426 return (Method && Method->isVirtual()) ? 1 : 0;
6427}
6428} // end: extern "C"
6429
6430//===----------------------------------------------------------------------===//
6431// Attribute introspection.
6432//===----------------------------------------------------------------------===//
6433
6434extern "C" {
6435CXType clang_getIBOutletCollectionType(CXCursor C) {
6436 if (C.kind != CXCursor_IBOutletCollectionAttr)
6437 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6438
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006439 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006440 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6441
6442 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6443}
6444} // end: extern "C"
6445
6446//===----------------------------------------------------------------------===//
6447// Inspecting memory usage.
6448//===----------------------------------------------------------------------===//
6449
6450typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6451
6452static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6453 enum CXTUResourceUsageKind k,
6454 unsigned long amount) {
6455 CXTUResourceUsageEntry entry = { k, amount };
6456 entries.push_back(entry);
6457}
6458
6459extern "C" {
6460
6461const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6462 const char *str = "";
6463 switch (kind) {
6464 case CXTUResourceUsage_AST:
6465 str = "ASTContext: expressions, declarations, and types";
6466 break;
6467 case CXTUResourceUsage_Identifiers:
6468 str = "ASTContext: identifiers";
6469 break;
6470 case CXTUResourceUsage_Selectors:
6471 str = "ASTContext: selectors";
6472 break;
6473 case CXTUResourceUsage_GlobalCompletionResults:
6474 str = "Code completion: cached global results";
6475 break;
6476 case CXTUResourceUsage_SourceManagerContentCache:
6477 str = "SourceManager: content cache allocator";
6478 break;
6479 case CXTUResourceUsage_AST_SideTables:
6480 str = "ASTContext: side tables";
6481 break;
6482 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6483 str = "SourceManager: malloc'ed memory buffers";
6484 break;
6485 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6486 str = "SourceManager: mmap'ed memory buffers";
6487 break;
6488 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6489 str = "ExternalASTSource: malloc'ed memory buffers";
6490 break;
6491 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6492 str = "ExternalASTSource: mmap'ed memory buffers";
6493 break;
6494 case CXTUResourceUsage_Preprocessor:
6495 str = "Preprocessor: malloc'ed memory";
6496 break;
6497 case CXTUResourceUsage_PreprocessingRecord:
6498 str = "Preprocessor: PreprocessingRecord";
6499 break;
6500 case CXTUResourceUsage_SourceManager_DataStructures:
6501 str = "SourceManager: data structures and tables";
6502 break;
6503 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6504 str = "Preprocessor: header search tables";
6505 break;
6506 }
6507 return str;
6508}
6509
6510CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006511 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006512 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006513 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6514 return usage;
6515 }
6516
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006517 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006518 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006519 ASTContext &astContext = astUnit->getASTContext();
6520
6521 // How much memory is used by AST nodes and types?
6522 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6523 (unsigned long) astContext.getASTAllocatedMemory());
6524
6525 // How much memory is used by identifiers?
6526 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6527 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6528
6529 // How much memory is used for selectors?
6530 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6531 (unsigned long) astContext.Selectors.getTotalMemory());
6532
6533 // How much memory is used by ASTContext's side tables?
6534 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6535 (unsigned long) astContext.getSideTableAllocatedMemory());
6536
6537 // How much memory is used for caching global code completion results?
6538 unsigned long completionBytes = 0;
6539 if (GlobalCodeCompletionAllocator *completionAllocator =
6540 astUnit->getCachedCompletionAllocator().getPtr()) {
6541 completionBytes = completionAllocator->getTotalMemory();
6542 }
6543 createCXTUResourceUsageEntry(*entries,
6544 CXTUResourceUsage_GlobalCompletionResults,
6545 completionBytes);
6546
6547 // How much memory is being used by SourceManager's content cache?
6548 createCXTUResourceUsageEntry(*entries,
6549 CXTUResourceUsage_SourceManagerContentCache,
6550 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6551
6552 // How much memory is being used by the MemoryBuffer's in SourceManager?
6553 const SourceManager::MemoryBufferSizes &srcBufs =
6554 astUnit->getSourceManager().getMemoryBufferSizes();
6555
6556 createCXTUResourceUsageEntry(*entries,
6557 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6558 (unsigned long) srcBufs.malloc_bytes);
6559 createCXTUResourceUsageEntry(*entries,
6560 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6561 (unsigned long) srcBufs.mmap_bytes);
6562 createCXTUResourceUsageEntry(*entries,
6563 CXTUResourceUsage_SourceManager_DataStructures,
6564 (unsigned long) astContext.getSourceManager()
6565 .getDataStructureSizes());
6566
6567 // How much memory is being used by the ExternalASTSource?
6568 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6569 const ExternalASTSource::MemoryBufferSizes &sizes =
6570 esrc->getMemoryBufferSizes();
6571
6572 createCXTUResourceUsageEntry(*entries,
6573 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6574 (unsigned long) sizes.malloc_bytes);
6575 createCXTUResourceUsageEntry(*entries,
6576 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6577 (unsigned long) sizes.mmap_bytes);
6578 }
6579
6580 // How much memory is being used by the Preprocessor?
6581 Preprocessor &pp = astUnit->getPreprocessor();
6582 createCXTUResourceUsageEntry(*entries,
6583 CXTUResourceUsage_Preprocessor,
6584 pp.getTotalMemory());
6585
6586 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6587 createCXTUResourceUsageEntry(*entries,
6588 CXTUResourceUsage_PreprocessingRecord,
6589 pRec->getTotalMemory());
6590 }
6591
6592 createCXTUResourceUsageEntry(*entries,
6593 CXTUResourceUsage_Preprocessor_HeaderSearch,
6594 pp.getHeaderSearchInfo().getTotalMemory());
6595
6596 CXTUResourceUsage usage = { (void*) entries.get(),
6597 (unsigned) entries->size(),
6598 entries->size() ? &(*entries)[0] : 0 };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006599 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006600 return usage;
6601}
6602
6603void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6604 if (usage.data)
6605 delete (MemUsageEntries*) usage.data;
6606}
6607
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006608CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6609 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006610 skipped->count = 0;
6611 skipped->ranges = 0;
6612
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006613 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006614 LOG_BAD_TU(TU);
6615 return skipped;
6616 }
6617
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006618 if (!file)
6619 return skipped;
6620
6621 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6622 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6623 if (!ppRec)
6624 return skipped;
6625
6626 ASTContext &Ctx = astUnit->getASTContext();
6627 SourceManager &sm = Ctx.getSourceManager();
6628 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6629 FileID wantedFileID = sm.translateFile(fileEntry);
6630
6631 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6632 std::vector<SourceRange> wantedRanges;
6633 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6634 i != ei; ++i) {
6635 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6636 wantedRanges.push_back(*i);
6637 }
6638
6639 skipped->count = wantedRanges.size();
6640 skipped->ranges = new CXSourceRange[skipped->count];
6641 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6642 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6643
6644 return skipped;
6645}
6646
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006647void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6648 if (ranges) {
6649 delete[] ranges->ranges;
6650 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006651 }
6652}
6653
Guy Benyei11169dd2012-12-18 14:30:41 +00006654} // end extern "C"
6655
6656void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6657 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6658 for (unsigned I = 0; I != Usage.numEntries; ++I)
6659 fprintf(stderr, " %s: %lu\n",
6660 clang_getTUResourceUsageName(Usage.entries[I].kind),
6661 Usage.entries[I].amount);
6662
6663 clang_disposeCXTUResourceUsage(Usage);
6664}
6665
6666//===----------------------------------------------------------------------===//
6667// Misc. utility functions.
6668//===----------------------------------------------------------------------===//
6669
6670/// Default to using an 8 MB stack size on "safety" threads.
6671static unsigned SafetyStackThreadSize = 8 << 20;
6672
6673namespace clang {
6674
6675bool RunSafely(llvm::CrashRecoveryContext &CRC,
6676 void (*Fn)(void*), void *UserData,
6677 unsigned Size) {
6678 if (!Size)
6679 Size = GetSafetyThreadStackSize();
6680 if (Size)
6681 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6682 return CRC.RunSafely(Fn, UserData);
6683}
6684
6685unsigned GetSafetyThreadStackSize() {
6686 return SafetyStackThreadSize;
6687}
6688
6689void SetSafetyThreadStackSize(unsigned Value) {
6690 SafetyStackThreadSize = Value;
6691}
6692
6693}
6694
6695void clang::setThreadBackgroundPriority() {
6696 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6697 return;
6698
6699 // FIXME: Move to llvm/Support and make it cross-platform.
6700#ifdef __APPLE__
6701 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6702#endif
6703}
6704
6705void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6706 if (!Unit)
6707 return;
6708
6709 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6710 DEnd = Unit->stored_diag_end();
6711 D != DEnd; ++D) {
6712 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6713 CXString Msg = clang_formatDiagnostic(&Diag,
6714 clang_defaultDiagnosticDisplayOptions());
6715 fprintf(stderr, "%s\n", clang_getCString(Msg));
6716 clang_disposeString(Msg);
6717 }
6718#ifdef LLVM_ON_WIN32
6719 // On Windows, force a flush, since there may be multiple copies of
6720 // stderr and stdout in the file system, all with different buffers
6721 // but writing to the same device.
6722 fflush(stderr);
6723#endif
6724}
6725
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006726MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6727 SourceLocation MacroDefLoc,
6728 CXTranslationUnit TU){
6729 if (MacroDefLoc.isInvalid() || !TU)
6730 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006731 if (!II.hadMacroDefinition())
6732 return 0;
6733
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006734 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006735 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006736 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006737 if (MD) {
6738 for (MacroDirective::DefInfo
6739 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6740 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6741 return Def.getMacroInfo();
6742 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006743 }
6744
6745 return 0;
6746}
6747
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006748const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6749 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006750 if (!MacroDef || !TU)
6751 return 0;
6752 const IdentifierInfo *II = MacroDef->getName();
6753 if (!II)
6754 return 0;
6755
6756 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6757}
6758
6759MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6760 const Token &Tok,
6761 CXTranslationUnit TU) {
6762 if (!MI || !TU)
6763 return 0;
6764 if (Tok.isNot(tok::raw_identifier))
6765 return 0;
6766
6767 if (MI->getNumTokens() == 0)
6768 return 0;
6769 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6770 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006771 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006772
6773 // Check that the token is inside the definition and not its argument list.
6774 SourceManager &SM = Unit->getSourceManager();
6775 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6776 return 0;
6777 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6778 return 0;
6779
6780 Preprocessor &PP = Unit->getPreprocessor();
6781 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6782 if (!PPRec)
6783 return 0;
6784
6785 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6786 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6787 if (!II.hadMacroDefinition())
6788 return 0;
6789
6790 // Check that the identifier is not one of the macro arguments.
6791 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6792 return 0;
6793
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006794 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6795 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006796 return 0;
6797
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006798 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006799}
6800
6801MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6802 SourceLocation Loc,
6803 CXTranslationUnit TU) {
6804 if (Loc.isInvalid() || !MI || !TU)
6805 return 0;
6806
6807 if (MI->getNumTokens() == 0)
6808 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006809 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006810 Preprocessor &PP = Unit->getPreprocessor();
6811 if (!PP.getPreprocessingRecord())
6812 return 0;
6813 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6814 Token Tok;
6815 if (PP.getRawToken(Loc, Tok))
6816 return 0;
6817
6818 return checkForMacroInMacroDefinition(MI, Tok, TU);
6819}
6820
Guy Benyei11169dd2012-12-18 14:30:41 +00006821extern "C" {
6822
6823CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006824 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006825}
6826
6827} // end: extern "C"
6828
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006829Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6830 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006831 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006832 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006833 if (Unit->isMainFileAST())
6834 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006835 return *this;
6836 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006837 } else {
6838 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006839 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006840 return *this;
6841}
6842
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006843Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6844 *this << FE->getName();
6845 return *this;
6846}
6847
6848Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6849 CXString cursorName = clang_getCursorDisplayName(cursor);
6850 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6851 clang_disposeString(cursorName);
6852 return *this;
6853}
6854
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006855Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6856 CXFile File;
6857 unsigned Line, Column;
6858 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6859 CXString FileName = clang_getFileName(File);
6860 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6861 clang_disposeString(FileName);
6862 return *this;
6863}
6864
6865Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6866 CXSourceLocation BLoc = clang_getRangeStart(range);
6867 CXSourceLocation ELoc = clang_getRangeEnd(range);
6868
6869 CXFile BFile;
6870 unsigned BLine, BColumn;
6871 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6872
6873 CXFile EFile;
6874 unsigned ELine, EColumn;
6875 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6876
6877 CXString BFileName = clang_getFileName(BFile);
6878 if (BFile == EFile) {
6879 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6880 BLine, BColumn, ELine, EColumn);
6881 } else {
6882 CXString EFileName = clang_getFileName(EFile);
6883 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6884 BLine, BColumn)
6885 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6886 ELine, EColumn);
6887 clang_disposeString(EFileName);
6888 }
6889 clang_disposeString(BFileName);
6890 return *this;
6891}
6892
6893Logger &cxindex::Logger::operator<<(CXString Str) {
6894 *this << clang_getCString(Str);
6895 return *this;
6896}
6897
6898Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6899 LogOS << Fmt;
6900 return *this;
6901}
6902
6903cxindex::Logger::~Logger() {
6904 LogOS.flush();
6905
6906 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6907
6908 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6909
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006910 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006911 OS << "[libclang:" << Name << ':';
6912
6913 // FIXME: Portability.
6914#if HAVE_PTHREAD_H && __APPLE__
6915 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6916 OS << tid << ':';
6917#endif
6918
6919 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6920 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6921 OS << Msg.str() << '\n';
6922
6923 if (Trace) {
6924 llvm::sys::PrintStackTrace(stderr);
6925 OS << "--------------------------------------------------\n";
6926 }
6927}