blob: 98563078447e9caf01dca263c1cba291c39a30d4 [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
919 for (ObjCMethodDecl::param_iterator P = ND->param_begin(),
920 PEnd = ND->param_end();
921 P != PEnd; ++P) {
922 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
923 return true;
924 }
925
926 if (ND->isThisDeclarationADefinition() &&
927 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
928 return true;
929
930 return false;
931}
932
933template <typename DeclIt>
934static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
935 SourceManager &SM, SourceLocation EndLoc,
936 SmallVectorImpl<Decl *> &Decls) {
937 DeclIt next = *DI_current;
938 while (++next != DE_current) {
939 Decl *D_next = *next;
940 if (!D_next)
941 break;
942 SourceLocation L = D_next->getLocStart();
943 if (!L.isValid())
944 break;
945 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
946 *DI_current = next;
947 Decls.push_back(D_next);
948 continue;
949 }
950 break;
951 }
952}
953
Guy Benyei11169dd2012-12-18 14:30:41 +0000954bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
955 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
956 // an @implementation can lexically contain Decls that are not properly
957 // nested in the AST. When we identify such cases, we need to retrofit
958 // this nesting here.
959 if (!DI_current && !FileDI_current)
960 return VisitDeclContext(D);
961
962 // Scan the Decls that immediately come after the container
963 // in the current DeclContext. If any fall within the
964 // container's lexical region, stash them into a vector
965 // for later processing.
966 SmallVector<Decl *, 24> DeclsInContainer;
967 SourceLocation EndLoc = D->getSourceRange().getEnd();
968 SourceManager &SM = AU->getSourceManager();
969 if (EndLoc.isValid()) {
970 if (DI_current) {
971 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
972 DeclsInContainer);
973 } else {
974 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
975 DeclsInContainer);
976 }
977 }
978
979 // The common case.
980 if (DeclsInContainer.empty())
981 return VisitDeclContext(D);
982
983 // Get all the Decls in the DeclContext, and sort them with the
984 // additional ones we've collected. Then visit them.
985 for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
986 I!=E; ++I) {
987 Decl *subDecl = *I;
988 if (!subDecl || subDecl->getLexicalDeclContext() != D ||
989 subDecl->getLocStart().isInvalid())
990 continue;
991 DeclsInContainer.push_back(subDecl);
992 }
993
994 // Now sort the Decls so that they appear in lexical order.
995 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000996 [&SM](Decl *A, Decl *B) {
997 SourceLocation L_A = A->getLocStart();
998 SourceLocation L_B = B->getLocStart();
999 assert(L_A.isValid() && L_B.isValid());
1000 return SM.isBeforeInTranslationUnit(L_A, L_B);
1001 });
Guy Benyei11169dd2012-12-18 14:30:41 +00001002
1003 // Now visit the decls.
1004 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
1005 E = DeclsInContainer.end(); I != E; ++I) {
1006 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001007 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001008 if (!V.hasValue())
1009 continue;
1010 if (!V.getValue())
1011 return false;
1012 if (Visit(Cursor, true))
1013 return true;
1014 }
1015 return false;
1016}
1017
1018bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1019 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1020 TU)))
1021 return true;
1022
1023 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1024 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1025 E = ND->protocol_end(); I != E; ++I, ++PL)
1026 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1027 return true;
1028
1029 return VisitObjCContainerDecl(ND);
1030}
1031
1032bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1033 if (!PID->isThisDeclarationADefinition())
1034 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1035
1036 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1037 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1038 E = PID->protocol_end(); I != E; ++I, ++PL)
1039 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1040 return true;
1041
1042 return VisitObjCContainerDecl(PID);
1043}
1044
1045bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1046 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1047 return true;
1048
1049 // FIXME: This implements a workaround with @property declarations also being
1050 // installed in the DeclContext for the @interface. Eventually this code
1051 // should be removed.
1052 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1053 if (!CDecl || !CDecl->IsClassExtension())
1054 return false;
1055
1056 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1057 if (!ID)
1058 return false;
1059
1060 IdentifierInfo *PropertyId = PD->getIdentifier();
1061 ObjCPropertyDecl *prevDecl =
1062 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1063
1064 if (!prevDecl)
1065 return false;
1066
1067 // Visit synthesized methods since they will be skipped when visiting
1068 // the @interface.
1069 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1070 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1071 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1072 return true;
1073
1074 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1075 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1076 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1077 return true;
1078
1079 return false;
1080}
1081
1082bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1083 if (!D->isThisDeclarationADefinition()) {
1084 // Forward declaration is treated like a reference.
1085 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1086 }
1087
1088 // Issue callbacks for super class.
1089 if (D->getSuperClass() &&
1090 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1091 D->getSuperClassLoc(),
1092 TU)))
1093 return true;
1094
1095 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1096 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1097 E = D->protocol_end(); I != E; ++I, ++PL)
1098 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1099 return true;
1100
1101 return VisitObjCContainerDecl(D);
1102}
1103
1104bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1105 return VisitObjCContainerDecl(D);
1106}
1107
1108bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1109 // 'ID' could be null when dealing with invalid code.
1110 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1111 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1112 return true;
1113
1114 return VisitObjCImplDecl(D);
1115}
1116
1117bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1118#if 0
1119 // Issue callbacks for super class.
1120 // FIXME: No source location information!
1121 if (D->getSuperClass() &&
1122 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1123 D->getSuperClassLoc(),
1124 TU)))
1125 return true;
1126#endif
1127
1128 return VisitObjCImplDecl(D);
1129}
1130
1131bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1132 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1133 if (PD->isIvarNameSpecified())
1134 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1135
1136 return false;
1137}
1138
1139bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1140 return VisitDeclContext(D);
1141}
1142
1143bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1144 // Visit nested-name-specifier.
1145 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1146 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1147 return true;
1148
1149 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1150 D->getTargetNameLoc(), TU));
1151}
1152
1153bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1154 // Visit nested-name-specifier.
1155 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1156 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1157 return true;
1158 }
1159
1160 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1161 return true;
1162
1163 return VisitDeclarationNameInfo(D->getNameInfo());
1164}
1165
1166bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1167 // Visit nested-name-specifier.
1168 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1169 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1170 return true;
1171
1172 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1173 D->getIdentLocation(), TU));
1174}
1175
1176bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1177 // Visit nested-name-specifier.
1178 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1179 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1180 return true;
1181 }
1182
1183 return VisitDeclarationNameInfo(D->getNameInfo());
1184}
1185
1186bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1187 UnresolvedUsingTypenameDecl *D) {
1188 // Visit nested-name-specifier.
1189 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1190 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1191 return true;
1192
1193 return false;
1194}
1195
1196bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1197 switch (Name.getName().getNameKind()) {
1198 case clang::DeclarationName::Identifier:
1199 case clang::DeclarationName::CXXLiteralOperatorName:
1200 case clang::DeclarationName::CXXOperatorName:
1201 case clang::DeclarationName::CXXUsingDirective:
1202 return false;
1203
1204 case clang::DeclarationName::CXXConstructorName:
1205 case clang::DeclarationName::CXXDestructorName:
1206 case clang::DeclarationName::CXXConversionFunctionName:
1207 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1208 return Visit(TSInfo->getTypeLoc());
1209 return false;
1210
1211 case clang::DeclarationName::ObjCZeroArgSelector:
1212 case clang::DeclarationName::ObjCOneArgSelector:
1213 case clang::DeclarationName::ObjCMultiArgSelector:
1214 // FIXME: Per-identifier location info?
1215 return false;
1216 }
1217
1218 llvm_unreachable("Invalid DeclarationName::Kind!");
1219}
1220
1221bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1222 SourceRange Range) {
1223 // FIXME: This whole routine is a hack to work around the lack of proper
1224 // source information in nested-name-specifiers (PR5791). Since we do have
1225 // a beginning source location, we can visit the first component of the
1226 // nested-name-specifier, if it's a single-token component.
1227 if (!NNS)
1228 return false;
1229
1230 // Get the first component in the nested-name-specifier.
1231 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1232 NNS = Prefix;
1233
1234 switch (NNS->getKind()) {
1235 case NestedNameSpecifier::Namespace:
1236 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1237 TU));
1238
1239 case NestedNameSpecifier::NamespaceAlias:
1240 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1241 Range.getBegin(), TU));
1242
1243 case NestedNameSpecifier::TypeSpec: {
1244 // If the type has a form where we know that the beginning of the source
1245 // range matches up with a reference cursor. Visit the appropriate reference
1246 // cursor.
1247 const Type *T = NNS->getAsType();
1248 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1249 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1250 if (const TagType *Tag = dyn_cast<TagType>(T))
1251 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1252 if (const TemplateSpecializationType *TST
1253 = dyn_cast<TemplateSpecializationType>(T))
1254 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1255 break;
1256 }
1257
1258 case NestedNameSpecifier::TypeSpecWithTemplate:
1259 case NestedNameSpecifier::Global:
1260 case NestedNameSpecifier::Identifier:
1261 break;
1262 }
1263
1264 return false;
1265}
1266
1267bool
1268CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1269 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1270 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1271 Qualifiers.push_back(Qualifier);
1272
1273 while (!Qualifiers.empty()) {
1274 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1275 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1276 switch (NNS->getKind()) {
1277 case NestedNameSpecifier::Namespace:
1278 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1279 Q.getLocalBeginLoc(),
1280 TU)))
1281 return true;
1282
1283 break;
1284
1285 case NestedNameSpecifier::NamespaceAlias:
1286 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1287 Q.getLocalBeginLoc(),
1288 TU)))
1289 return true;
1290
1291 break;
1292
1293 case NestedNameSpecifier::TypeSpec:
1294 case NestedNameSpecifier::TypeSpecWithTemplate:
1295 if (Visit(Q.getTypeLoc()))
1296 return true;
1297
1298 break;
1299
1300 case NestedNameSpecifier::Global:
1301 case NestedNameSpecifier::Identifier:
1302 break;
1303 }
1304 }
1305
1306 return false;
1307}
1308
1309bool CursorVisitor::VisitTemplateParameters(
1310 const TemplateParameterList *Params) {
1311 if (!Params)
1312 return false;
1313
1314 for (TemplateParameterList::const_iterator P = Params->begin(),
1315 PEnd = Params->end();
1316 P != PEnd; ++P) {
1317 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1318 return true;
1319 }
1320
1321 return false;
1322}
1323
1324bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1325 switch (Name.getKind()) {
1326 case TemplateName::Template:
1327 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1328
1329 case TemplateName::OverloadedTemplate:
1330 // Visit the overloaded template set.
1331 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1332 return true;
1333
1334 return false;
1335
1336 case TemplateName::DependentTemplate:
1337 // FIXME: Visit nested-name-specifier.
1338 return false;
1339
1340 case TemplateName::QualifiedTemplate:
1341 // FIXME: Visit nested-name-specifier.
1342 return Visit(MakeCursorTemplateRef(
1343 Name.getAsQualifiedTemplateName()->getDecl(),
1344 Loc, TU));
1345
1346 case TemplateName::SubstTemplateTemplateParm:
1347 return Visit(MakeCursorTemplateRef(
1348 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1349 Loc, TU));
1350
1351 case TemplateName::SubstTemplateTemplateParmPack:
1352 return Visit(MakeCursorTemplateRef(
1353 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1354 Loc, TU));
1355 }
1356
1357 llvm_unreachable("Invalid TemplateName::Kind!");
1358}
1359
1360bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1361 switch (TAL.getArgument().getKind()) {
1362 case TemplateArgument::Null:
1363 case TemplateArgument::Integral:
1364 case TemplateArgument::Pack:
1365 return false;
1366
1367 case TemplateArgument::Type:
1368 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1369 return Visit(TSInfo->getTypeLoc());
1370 return false;
1371
1372 case TemplateArgument::Declaration:
1373 if (Expr *E = TAL.getSourceDeclExpression())
1374 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1375 return false;
1376
1377 case TemplateArgument::NullPtr:
1378 if (Expr *E = TAL.getSourceNullPtrExpression())
1379 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1380 return false;
1381
1382 case TemplateArgument::Expression:
1383 if (Expr *E = TAL.getSourceExpression())
1384 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1385 return false;
1386
1387 case TemplateArgument::Template:
1388 case TemplateArgument::TemplateExpansion:
1389 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1390 return true;
1391
1392 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1393 TAL.getTemplateNameLoc());
1394 }
1395
1396 llvm_unreachable("Invalid TemplateArgument::Kind!");
1397}
1398
1399bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1400 return VisitDeclContext(D);
1401}
1402
1403bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1404 return Visit(TL.getUnqualifiedLoc());
1405}
1406
1407bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1408 ASTContext &Context = AU->getASTContext();
1409
1410 // Some builtin types (such as Objective-C's "id", "sel", and
1411 // "Class") have associated declarations. Create cursors for those.
1412 QualType VisitType;
1413 switch (TL.getTypePtr()->getKind()) {
1414
1415 case BuiltinType::Void:
1416 case BuiltinType::NullPtr:
1417 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001418 case BuiltinType::OCLImage1d:
1419 case BuiltinType::OCLImage1dArray:
1420 case BuiltinType::OCLImage1dBuffer:
1421 case BuiltinType::OCLImage2d:
1422 case BuiltinType::OCLImage2dArray:
1423 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001424 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001425 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001426#define BUILTIN_TYPE(Id, SingletonId)
1427#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1428#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1429#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1430#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1431#include "clang/AST/BuiltinTypes.def"
1432 break;
1433
1434 case BuiltinType::ObjCId:
1435 VisitType = Context.getObjCIdType();
1436 break;
1437
1438 case BuiltinType::ObjCClass:
1439 VisitType = Context.getObjCClassType();
1440 break;
1441
1442 case BuiltinType::ObjCSel:
1443 VisitType = Context.getObjCSelType();
1444 break;
1445 }
1446
1447 if (!VisitType.isNull()) {
1448 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1449 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1450 TU));
1451 }
1452
1453 return false;
1454}
1455
1456bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1457 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1458}
1459
1460bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1461 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1462}
1463
1464bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1465 if (TL.isDefinition())
1466 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1467
1468 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1469}
1470
1471bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1472 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1473}
1474
1475bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1476 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1477 return true;
1478
1479 return false;
1480}
1481
1482bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1483 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1484 return true;
1485
1486 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1487 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1488 TU)))
1489 return true;
1490 }
1491
1492 return false;
1493}
1494
1495bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1496 return Visit(TL.getPointeeLoc());
1497}
1498
1499bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1500 return Visit(TL.getInnerLoc());
1501}
1502
1503bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1504 return Visit(TL.getPointeeLoc());
1505}
1506
1507bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1508 return Visit(TL.getPointeeLoc());
1509}
1510
1511bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1512 return Visit(TL.getPointeeLoc());
1513}
1514
1515bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1516 return Visit(TL.getPointeeLoc());
1517}
1518
1519bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1520 return Visit(TL.getPointeeLoc());
1521}
1522
1523bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1524 return Visit(TL.getModifiedLoc());
1525}
1526
1527bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1528 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001529 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001530 return true;
1531
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001532 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1533 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001534 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1535 return true;
1536
1537 return false;
1538}
1539
1540bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1541 if (Visit(TL.getElementLoc()))
1542 return true;
1543
1544 if (Expr *Size = TL.getSizeExpr())
1545 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1546
1547 return false;
1548}
1549
Reid Kleckner8a365022013-06-24 17:51:48 +00001550bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1551 return Visit(TL.getOriginalLoc());
1552}
1553
Reid Kleckner0503a872013-12-05 01:23:43 +00001554bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1555 return Visit(TL.getOriginalLoc());
1556}
1557
Guy Benyei11169dd2012-12-18 14:30:41 +00001558bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1559 TemplateSpecializationTypeLoc TL) {
1560 // Visit the template name.
1561 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1562 TL.getTemplateNameLoc()))
1563 return true;
1564
1565 // Visit the template arguments.
1566 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1567 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1568 return true;
1569
1570 return false;
1571}
1572
1573bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1574 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1575}
1576
1577bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1578 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1579 return Visit(TSInfo->getTypeLoc());
1580
1581 return false;
1582}
1583
1584bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1585 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1586 return Visit(TSInfo->getTypeLoc());
1587
1588 return false;
1589}
1590
1591bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1592 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1593 return true;
1594
1595 return false;
1596}
1597
1598bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1599 DependentTemplateSpecializationTypeLoc TL) {
1600 // Visit the nested-name-specifier, if there is one.
1601 if (TL.getQualifierLoc() &&
1602 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1603 return true;
1604
1605 // Visit the template arguments.
1606 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1607 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1608 return true;
1609
1610 return false;
1611}
1612
1613bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1614 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1615 return true;
1616
1617 return Visit(TL.getNamedTypeLoc());
1618}
1619
1620bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1621 return Visit(TL.getPatternLoc());
1622}
1623
1624bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1625 if (Expr *E = TL.getUnderlyingExpr())
1626 return Visit(MakeCXCursor(E, StmtParent, TU));
1627
1628 return false;
1629}
1630
1631bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1632 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1633}
1634
1635bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1636 return Visit(TL.getValueLoc());
1637}
1638
1639#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1640bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1641 return Visit##PARENT##Loc(TL); \
1642}
1643
1644DEFAULT_TYPELOC_IMPL(Complex, Type)
1645DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1646DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1647DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1648DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1649DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1650DEFAULT_TYPELOC_IMPL(Vector, Type)
1651DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1652DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1653DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1654DEFAULT_TYPELOC_IMPL(Record, TagType)
1655DEFAULT_TYPELOC_IMPL(Enum, TagType)
1656DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1657DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1658DEFAULT_TYPELOC_IMPL(Auto, Type)
1659
1660bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1661 // Visit the nested-name-specifier, if present.
1662 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1663 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1664 return true;
1665
1666 if (D->isCompleteDefinition()) {
1667 for (CXXRecordDecl::base_class_iterator I = D->bases_begin(),
1668 E = D->bases_end(); I != E; ++I) {
1669 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(I, TU)))
1670 return true;
1671 }
1672 }
1673
1674 return VisitTagDecl(D);
1675}
1676
1677bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballman69082962014-03-07 12:50:00 +00001678 for (auto I : D->attrs())
1679 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001680 return true;
1681
1682 return false;
1683}
1684
1685//===----------------------------------------------------------------------===//
1686// Data-recursive visitor methods.
1687//===----------------------------------------------------------------------===//
1688
1689namespace {
1690#define DEF_JOB(NAME, DATA, KIND)\
1691class NAME : public VisitorJob {\
1692public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001693 NAME(const DATA *d, CXCursor parent) : \
1694 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001695 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001696 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001697};
1698
1699DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1700DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1701DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1702DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1703DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1704 ExplicitTemplateArgsVisitKind)
1705DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1706DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1707DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1708#undef DEF_JOB
1709
1710class DeclVisit : public VisitorJob {
1711public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001712 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001713 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001714 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001715 static bool classof(const VisitorJob *VJ) {
1716 return VJ->getKind() == DeclVisitKind;
1717 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001718 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001719 bool isFirst() const { return data[1] ? true : false; }
1720};
1721class TypeLocVisit : public VisitorJob {
1722public:
1723 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1724 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1725 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1726
1727 static bool classof(const VisitorJob *VJ) {
1728 return VJ->getKind() == TypeLocVisitKind;
1729 }
1730
1731 TypeLoc get() const {
1732 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001733 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001734 }
1735};
1736
1737class LabelRefVisit : public VisitorJob {
1738public:
1739 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1740 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1741 labelLoc.getPtrEncoding()) {}
1742
1743 static bool classof(const VisitorJob *VJ) {
1744 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1745 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001746 const LabelDecl *get() const {
1747 return static_cast<const LabelDecl *>(data[0]);
1748 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001749 SourceLocation getLoc() const {
1750 return SourceLocation::getFromPtrEncoding(data[1]); }
1751};
1752
1753class NestedNameSpecifierLocVisit : public VisitorJob {
1754public:
1755 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1756 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1757 Qualifier.getNestedNameSpecifier(),
1758 Qualifier.getOpaqueData()) { }
1759
1760 static bool classof(const VisitorJob *VJ) {
1761 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1762 }
1763
1764 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001765 return NestedNameSpecifierLoc(
1766 const_cast<NestedNameSpecifier *>(
1767 static_cast<const NestedNameSpecifier *>(data[0])),
1768 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001769 }
1770};
1771
1772class DeclarationNameInfoVisit : public VisitorJob {
1773public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001774 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001775 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001776 static bool classof(const VisitorJob *VJ) {
1777 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1778 }
1779 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001780 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001781 switch (S->getStmtClass()) {
1782 default:
1783 llvm_unreachable("Unhandled Stmt");
1784 case clang::Stmt::MSDependentExistsStmtClass:
1785 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1786 case Stmt::CXXDependentScopeMemberExprClass:
1787 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1788 case Stmt::DependentScopeDeclRefExprClass:
1789 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1790 }
1791 }
1792};
1793class MemberRefVisit : public VisitorJob {
1794public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001795 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001796 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1797 L.getPtrEncoding()) {}
1798 static bool classof(const VisitorJob *VJ) {
1799 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1800 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001801 const FieldDecl *get() const {
1802 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001803 }
1804 SourceLocation getLoc() const {
1805 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1806 }
1807};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001808class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001809 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001810 VisitorWorkList &WL;
1811 CXCursor Parent;
1812public:
1813 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1814 : WL(wl), Parent(parent) {}
1815
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001816 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1817 void VisitBlockExpr(const BlockExpr *B);
1818 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1819 void VisitCompoundStmt(const CompoundStmt *S);
1820 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1821 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1822 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1823 void VisitCXXNewExpr(const CXXNewExpr *E);
1824 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1825 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1826 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1827 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1828 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1829 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1830 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1831 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1832 void VisitDeclRefExpr(const DeclRefExpr *D);
1833 void VisitDeclStmt(const DeclStmt *S);
1834 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1835 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1836 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1837 void VisitForStmt(const ForStmt *FS);
1838 void VisitGotoStmt(const GotoStmt *GS);
1839 void VisitIfStmt(const IfStmt *If);
1840 void VisitInitListExpr(const InitListExpr *IE);
1841 void VisitMemberExpr(const MemberExpr *M);
1842 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1843 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1844 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1845 void VisitOverloadExpr(const OverloadExpr *E);
1846 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1847 void VisitStmt(const Stmt *S);
1848 void VisitSwitchStmt(const SwitchStmt *S);
1849 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001850 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1851 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1852 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1853 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1854 void VisitVAArgExpr(const VAArgExpr *E);
1855 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1856 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1857 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1858 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001859 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1860 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001861 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001862
Guy Benyei11169dd2012-12-18 14:30:41 +00001863private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001864 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001865 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1866 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001867 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1868 void AddStmt(const Stmt *S);
1869 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001870 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001871 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001872 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001873};
1874} // end anonyous namespace
1875
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001876void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001877 // 'S' should always be non-null, since it comes from the
1878 // statement we are visiting.
1879 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1880}
1881
1882void
1883EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1884 if (Qualifier)
1885 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1886}
1887
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001888void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001889 if (S)
1890 WL.push_back(StmtVisit(S, Parent));
1891}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001892void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001893 if (D)
1894 WL.push_back(DeclVisit(D, Parent, isFirst));
1895}
1896void EnqueueVisitor::
1897 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1898 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001899 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001900}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001901void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001902 if (D)
1903 WL.push_back(MemberRefVisit(D, L, Parent));
1904}
1905void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1906 if (TI)
1907 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1908 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001909void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001910 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001911 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001912 AddStmt(*Child);
1913 }
1914 if (size == WL.size())
1915 return;
1916 // Now reverse the entries we just added. This will match the DFS
1917 // ordering performed by the worklist.
1918 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1919 std::reverse(I, E);
1920}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001921namespace {
1922class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1923 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001924 /// \brief Process clauses with list of variables.
1925 template <typename T>
1926 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001927public:
1928 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1929#define OPENMP_CLAUSE(Name, Class) \
1930 void Visit##Class(const Class *C);
1931#include "clang/Basic/OpenMPKinds.def"
1932};
1933
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001934void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1935 Visitor->AddStmt(C->getCondition());
1936}
1937
Alexey Bataev568a8332014-03-06 06:15:19 +00001938void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1939 Visitor->AddStmt(C->getNumThreads());
1940}
1941
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001942void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001943
1944template<typename T>
1945void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
1946 for (typename T::varlist_const_iterator I = Node->varlist_begin(),
1947 E = Node->varlist_end();
1948 I != E; ++I)
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001949 Visitor->AddStmt(*I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001950}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001951
1952void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001953 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001954}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001955void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1956 const OMPFirstprivateClause *C) {
1957 VisitOMPClauseList(C);
1958}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001959void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001960 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001961}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001962}
Alexey Bataev756c1962013-09-24 03:17:45 +00001963
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001964void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1965 unsigned size = WL.size();
1966 OMPClauseEnqueue Visitor(this);
1967 Visitor.Visit(S);
1968 if (size == WL.size())
1969 return;
1970 // Now reverse the entries we just added. This will match the DFS
1971 // ordering performed by the worklist.
1972 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1973 std::reverse(I, E);
1974}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001975void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001976 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1977}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001978void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001979 AddDecl(B->getBlockDecl());
1980}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001981void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001982 EnqueueChildren(E);
1983 AddTypeLoc(E->getTypeSourceInfo());
1984}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001985void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1986 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001987 E = S->body_rend(); I != E; ++I) {
1988 AddStmt(*I);
1989 }
1990}
1991void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001992VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001993 AddStmt(S->getSubStmt());
1994 AddDeclarationNameInfo(S);
1995 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1996 AddNestedNameSpecifierLoc(QualifierLoc);
1997}
1998
1999void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002000VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002001 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2002 AddDeclarationNameInfo(E);
2003 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2004 AddNestedNameSpecifierLoc(QualifierLoc);
2005 if (!E->isImplicitAccess())
2006 AddStmt(E->getBase());
2007}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002008void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002009 // Enqueue the initializer , if any.
2010 AddStmt(E->getInitializer());
2011 // Enqueue the array size, if any.
2012 AddStmt(E->getArraySize());
2013 // Enqueue the allocated type.
2014 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2015 // Enqueue the placement arguments.
2016 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2017 AddStmt(E->getPlacementArg(I-1));
2018}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002019void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002020 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2021 AddStmt(CE->getArg(I-1));
2022 AddStmt(CE->getCallee());
2023 AddStmt(CE->getArg(0));
2024}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002025void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2026 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002027 // Visit the name of the type being destroyed.
2028 AddTypeLoc(E->getDestroyedTypeInfo());
2029 // Visit the scope type that looks disturbingly like the nested-name-specifier
2030 // but isn't.
2031 AddTypeLoc(E->getScopeTypeInfo());
2032 // Visit the nested-name-specifier.
2033 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2034 AddNestedNameSpecifierLoc(QualifierLoc);
2035 // Visit base expression.
2036 AddStmt(E->getBase());
2037}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002038void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2039 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002040 AddTypeLoc(E->getTypeSourceInfo());
2041}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002042void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2043 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002044 EnqueueChildren(E);
2045 AddTypeLoc(E->getTypeSourceInfo());
2046}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002047void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002048 EnqueueChildren(E);
2049 if (E->isTypeOperand())
2050 AddTypeLoc(E->getTypeOperandSourceInfo());
2051}
2052
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002053void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2054 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002055 EnqueueChildren(E);
2056 AddTypeLoc(E->getTypeSourceInfo());
2057}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002058void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002059 EnqueueChildren(E);
2060 if (E->isTypeOperand())
2061 AddTypeLoc(E->getTypeOperandSourceInfo());
2062}
2063
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002064void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002065 EnqueueChildren(S);
2066 AddDecl(S->getExceptionDecl());
2067}
2068
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002069void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002070 if (DR->hasExplicitTemplateArgs()) {
2071 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2072 }
2073 WL.push_back(DeclRefExprParts(DR, Parent));
2074}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002075void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2076 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002077 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2078 AddDeclarationNameInfo(E);
2079 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2080}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002081void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002082 unsigned size = WL.size();
2083 bool isFirst = true;
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002084 for (DeclStmt::const_decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00002085 D != DEnd; ++D) {
2086 AddDecl(*D, isFirst);
2087 isFirst = false;
2088 }
2089 if (size == WL.size())
2090 return;
2091 // Now reverse the entries we just added. This will match the DFS
2092 // ordering performed by the worklist.
2093 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2094 std::reverse(I, E);
2095}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002096void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002097 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002098 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002099 D = E->designators_rbegin(), DEnd = E->designators_rend();
2100 D != DEnd; ++D) {
2101 if (D->isFieldDesignator()) {
2102 if (FieldDecl *Field = D->getField())
2103 AddMemberRef(Field, D->getFieldLoc());
2104 continue;
2105 }
2106 if (D->isArrayDesignator()) {
2107 AddStmt(E->getArrayIndex(*D));
2108 continue;
2109 }
2110 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2111 AddStmt(E->getArrayRangeEnd(*D));
2112 AddStmt(E->getArrayRangeStart(*D));
2113 }
2114}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002115void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002116 EnqueueChildren(E);
2117 AddTypeLoc(E->getTypeInfoAsWritten());
2118}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002119void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002120 AddStmt(FS->getBody());
2121 AddStmt(FS->getInc());
2122 AddStmt(FS->getCond());
2123 AddDecl(FS->getConditionVariable());
2124 AddStmt(FS->getInit());
2125}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002126void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002127 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2128}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002129void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002130 AddStmt(If->getElse());
2131 AddStmt(If->getThen());
2132 AddStmt(If->getCond());
2133 AddDecl(If->getConditionVariable());
2134}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002135void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002136 // We care about the syntactic form of the initializer list, only.
2137 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2138 IE = Syntactic;
2139 EnqueueChildren(IE);
2140}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002141void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002142 WL.push_back(MemberExprParts(M, Parent));
2143
2144 // If the base of the member access expression is an implicit 'this', don't
2145 // visit it.
2146 // FIXME: If we ever want to show these implicit accesses, this will be
2147 // unfortunate. However, clang_getCursor() relies on this behavior.
2148 if (!M->isImplicitAccess())
2149 AddStmt(M->getBase());
2150}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002151void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002152 AddTypeLoc(E->getEncodedTypeSourceInfo());
2153}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002154void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002155 EnqueueChildren(M);
2156 AddTypeLoc(M->getClassReceiverTypeInfo());
2157}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002158void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002159 // Visit the components of the offsetof expression.
2160 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2161 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2162 const OffsetOfNode &Node = E->getComponent(I-1);
2163 switch (Node.getKind()) {
2164 case OffsetOfNode::Array:
2165 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2166 break;
2167 case OffsetOfNode::Field:
2168 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2169 break;
2170 case OffsetOfNode::Identifier:
2171 case OffsetOfNode::Base:
2172 continue;
2173 }
2174 }
2175 // Visit the type into which we're computing the offset.
2176 AddTypeLoc(E->getTypeSourceInfo());
2177}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002178void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002179 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2180 WL.push_back(OverloadExprParts(E, Parent));
2181}
2182void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002183 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002184 EnqueueChildren(E);
2185 if (E->isArgumentType())
2186 AddTypeLoc(E->getArgumentTypeInfo());
2187}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002188void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002189 EnqueueChildren(S);
2190}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002191void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002192 AddStmt(S->getBody());
2193 AddStmt(S->getCond());
2194 AddDecl(S->getConditionVariable());
2195}
2196
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002197void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002198 AddStmt(W->getBody());
2199 AddStmt(W->getCond());
2200 AddDecl(W->getConditionVariable());
2201}
2202
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002203void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002204 for (unsigned I = E->getNumArgs(); I > 0; --I)
2205 AddTypeLoc(E->getArg(I-1));
2206}
2207
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002208void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002209 AddTypeLoc(E->getQueriedTypeSourceInfo());
2210}
2211
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002212void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002213 EnqueueChildren(E);
2214}
2215
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002216void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002217 VisitOverloadExpr(U);
2218 if (!U->isImplicitAccess())
2219 AddStmt(U->getBase());
2220}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002221void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002222 AddStmt(E->getSubExpr());
2223 AddTypeLoc(E->getWrittenTypeInfo());
2224}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002225void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002226 WL.push_back(SizeOfPackExprParts(E, Parent));
2227}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002228void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002229 // If the opaque value has a source expression, just transparently
2230 // visit that. This is useful for (e.g.) pseudo-object expressions.
2231 if (Expr *SourceExpr = E->getSourceExpr())
2232 return Visit(SourceExpr);
2233}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002234void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002235 AddStmt(E->getBody());
2236 WL.push_back(LambdaExprParts(E, Parent));
2237}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002238void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002239 // Treat the expression like its syntactic form.
2240 Visit(E->getSyntacticForm());
2241}
2242
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002243void EnqueueVisitor::VisitOMPExecutableDirective(
2244 const OMPExecutableDirective *D) {
2245 EnqueueChildren(D);
2246 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2247 E = D->clauses().end();
2248 I != E; ++I)
2249 EnqueueChildren(*I);
2250}
2251
2252void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2253 VisitOMPExecutableDirective(D);
2254}
2255
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002256void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2257 VisitOMPExecutableDirective(D);
2258}
2259
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002260void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002261 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2262}
2263
2264bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2265 if (RegionOfInterest.isValid()) {
2266 SourceRange Range = getRawCursorExtent(C);
2267 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2268 return false;
2269 }
2270 return true;
2271}
2272
2273bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2274 while (!WL.empty()) {
2275 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002276 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002277
2278 // Set the Parent field, then back to its old value once we're done.
2279 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2280
2281 switch (LI.getKind()) {
2282 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002283 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002284 if (!D)
2285 continue;
2286
2287 // For now, perform default visitation for Decls.
2288 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2289 cast<DeclVisit>(&LI)->isFirst())))
2290 return true;
2291
2292 continue;
2293 }
2294 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2295 const ASTTemplateArgumentListInfo *ArgList =
2296 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2297 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2298 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2299 Arg != ArgEnd; ++Arg) {
2300 if (VisitTemplateArgumentLoc(*Arg))
2301 return true;
2302 }
2303 continue;
2304 }
2305 case VisitorJob::TypeLocVisitKind: {
2306 // Perform default visitation for TypeLocs.
2307 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2308 return true;
2309 continue;
2310 }
2311 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002312 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002313 if (LabelStmt *stmt = LS->getStmt()) {
2314 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2315 TU))) {
2316 return true;
2317 }
2318 }
2319 continue;
2320 }
2321
2322 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2323 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2324 if (VisitNestedNameSpecifierLoc(V->get()))
2325 return true;
2326 continue;
2327 }
2328
2329 case VisitorJob::DeclarationNameInfoVisitKind: {
2330 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2331 ->get()))
2332 return true;
2333 continue;
2334 }
2335 case VisitorJob::MemberRefVisitKind: {
2336 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2337 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2338 return true;
2339 continue;
2340 }
2341 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002342 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002343 if (!S)
2344 continue;
2345
2346 // Update the current cursor.
2347 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2348 if (!IsInRegionOfInterest(Cursor))
2349 continue;
2350 switch (Visitor(Cursor, Parent, ClientData)) {
2351 case CXChildVisit_Break: return true;
2352 case CXChildVisit_Continue: break;
2353 case CXChildVisit_Recurse:
2354 if (PostChildrenVisitor)
2355 WL.push_back(PostChildrenVisit(0, Cursor));
2356 EnqueueWorkList(WL, S);
2357 break;
2358 }
2359 continue;
2360 }
2361 case VisitorJob::MemberExprPartsKind: {
2362 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002363 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002364
2365 // Visit the nested-name-specifier
2366 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2367 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2368 return true;
2369
2370 // Visit the declaration name.
2371 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2372 return true;
2373
2374 // Visit the explicitly-specified template arguments, if any.
2375 if (M->hasExplicitTemplateArgs()) {
2376 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2377 *ArgEnd = Arg + M->getNumTemplateArgs();
2378 Arg != ArgEnd; ++Arg) {
2379 if (VisitTemplateArgumentLoc(*Arg))
2380 return true;
2381 }
2382 }
2383 continue;
2384 }
2385 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002386 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002387 // Visit nested-name-specifier, if present.
2388 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2389 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2390 return true;
2391 // Visit declaration name.
2392 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2393 return true;
2394 continue;
2395 }
2396 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002397 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002398 // Visit the nested-name-specifier.
2399 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2400 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2401 return true;
2402 // Visit the declaration name.
2403 if (VisitDeclarationNameInfo(O->getNameInfo()))
2404 return true;
2405 // Visit the overloaded declaration reference.
2406 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2407 return true;
2408 continue;
2409 }
2410 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002411 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002412 NamedDecl *Pack = E->getPack();
2413 if (isa<TemplateTypeParmDecl>(Pack)) {
2414 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2415 E->getPackLoc(), TU)))
2416 return true;
2417
2418 continue;
2419 }
2420
2421 if (isa<TemplateTemplateParmDecl>(Pack)) {
2422 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2423 E->getPackLoc(), TU)))
2424 return true;
2425
2426 continue;
2427 }
2428
2429 // Non-type template parameter packs and function parameter packs are
2430 // treated like DeclRefExpr cursors.
2431 continue;
2432 }
2433
2434 case VisitorJob::LambdaExprPartsKind: {
2435 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002436 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002437 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2438 CEnd = E->explicit_capture_end();
2439 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002440 // FIXME: Lambda init-captures.
2441 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002442 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002443
Guy Benyei11169dd2012-12-18 14:30:41 +00002444 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2445 C->getLocation(),
2446 TU)))
2447 return true;
2448 }
2449
2450 // Visit parameters and return type, if present.
2451 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2452 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2453 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2454 // Visit the whole type.
2455 if (Visit(TL))
2456 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002457 } else if (FunctionProtoTypeLoc Proto =
2458 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002459 if (E->hasExplicitParameters()) {
2460 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002461 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2462 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002463 return true;
2464 } else {
2465 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002466 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002467 return true;
2468 }
2469 }
2470 }
2471 break;
2472 }
2473
2474 case VisitorJob::PostChildrenVisitKind:
2475 if (PostChildrenVisitor(Parent, ClientData))
2476 return true;
2477 break;
2478 }
2479 }
2480 return false;
2481}
2482
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002483bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002484 VisitorWorkList *WL = 0;
2485 if (!WorkListFreeList.empty()) {
2486 WL = WorkListFreeList.back();
2487 WL->clear();
2488 WorkListFreeList.pop_back();
2489 }
2490 else {
2491 WL = new VisitorWorkList();
2492 WorkListCache.push_back(WL);
2493 }
2494 EnqueueWorkList(*WL, S);
2495 bool result = RunVisitorWorkList(*WL);
2496 WorkListFreeList.push_back(WL);
2497 return result;
2498}
2499
2500namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002501typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002502RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2503 const DeclarationNameInfo &NI,
2504 const SourceRange &QLoc,
2505 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2506 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2507 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2508 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2509
2510 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2511
2512 RefNamePieces Pieces;
2513
2514 if (WantQualifier && QLoc.isValid())
2515 Pieces.push_back(QLoc);
2516
2517 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2518 Pieces.push_back(NI.getLoc());
2519
2520 if (WantTemplateArgs && TemplateArgs)
2521 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2522 TemplateArgs->RAngleLoc));
2523
2524 if (Kind == DeclarationName::CXXOperatorName) {
2525 Pieces.push_back(SourceLocation::getFromRawEncoding(
2526 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2527 Pieces.push_back(SourceLocation::getFromRawEncoding(
2528 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2529 }
2530
2531 if (WantSinglePiece) {
2532 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2533 Pieces.clear();
2534 Pieces.push_back(R);
2535 }
2536
2537 return Pieces;
2538}
2539}
2540
2541//===----------------------------------------------------------------------===//
2542// Misc. API hooks.
2543//===----------------------------------------------------------------------===//
2544
2545static llvm::sys::Mutex EnableMultithreadingMutex;
2546static bool EnabledMultithreading;
2547
Chad Rosier05c71aa2013-03-27 18:28:23 +00002548static void fatal_error_handler(void *user_data, const std::string& reason,
2549 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002550 // Write the result out to stderr avoiding errs() because raw_ostreams can
2551 // call report_fatal_error.
2552 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2553 ::abort();
2554}
2555
2556extern "C" {
2557CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2558 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002559 // We use crash recovery to make some of our APIs more reliable, implicitly
2560 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002561 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2562 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002563
2564 // Enable support for multithreading in LLVM.
2565 {
2566 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2567 if (!EnabledMultithreading) {
2568 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2569 llvm::llvm_start_multithreaded();
2570 EnabledMultithreading = true;
2571 }
2572 }
2573
2574 CIndexer *CIdxr = new CIndexer();
2575 if (excludeDeclarationsFromPCH)
2576 CIdxr->setOnlyLocalDecls();
2577 if (displayDiagnostics)
2578 CIdxr->setDisplayDiagnostics();
2579
2580 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2581 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2582 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2583 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2584 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2585 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2586
2587 return CIdxr;
2588}
2589
2590void clang_disposeIndex(CXIndex CIdx) {
2591 if (CIdx)
2592 delete static_cast<CIndexer *>(CIdx);
2593}
2594
2595void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2596 if (CIdx)
2597 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2598}
2599
2600unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2601 if (CIdx)
2602 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2603 return 0;
2604}
2605
2606void clang_toggleCrashRecovery(unsigned isEnabled) {
2607 if (isEnabled)
2608 llvm::CrashRecoveryContext::Enable();
2609 else
2610 llvm::CrashRecoveryContext::Disable();
2611}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002612
Guy Benyei11169dd2012-12-18 14:30:41 +00002613CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2614 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002615 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002616 enum CXErrorCode Result =
2617 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002618 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002619 assert((TU && Result == CXError_Success) ||
2620 (!TU && Result != CXError_Success));
2621 return TU;
2622}
2623
2624enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2625 const char *ast_filename,
2626 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002627 if (out_TU)
2628 *out_TU = NULL;
2629
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002630 if (!CIdx || !ast_filename || !out_TU)
2631 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002632
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002633 LOG_FUNC_SECTION {
2634 *Log << ast_filename;
2635 }
2636
Guy Benyei11169dd2012-12-18 14:30:41 +00002637 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2638 FileSystemOptions FileSystemOpts;
2639
2640 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002641 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002642 CXXIdx->getOnlyLocalDecls(), None,
2643 /*CaptureDiagnostics=*/true,
2644 /*AllowPCHWithCompilerErrors=*/true,
2645 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002646 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2647 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002648}
2649
2650unsigned clang_defaultEditingTranslationUnitOptions() {
2651 return CXTranslationUnit_PrecompiledPreamble |
2652 CXTranslationUnit_CacheCompletionResults;
2653}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002654
Guy Benyei11169dd2012-12-18 14:30:41 +00002655CXTranslationUnit
2656clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2657 const char *source_filename,
2658 int num_command_line_args,
2659 const char * const *command_line_args,
2660 unsigned num_unsaved_files,
2661 struct CXUnsavedFile *unsaved_files) {
2662 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2663 return clang_parseTranslationUnit(CIdx, source_filename,
2664 command_line_args, num_command_line_args,
2665 unsaved_files, num_unsaved_files,
2666 Options);
2667}
2668
2669struct ParseTranslationUnitInfo {
2670 CXIndex CIdx;
2671 const char *source_filename;
2672 const char *const *command_line_args;
2673 int num_command_line_args;
2674 struct CXUnsavedFile *unsaved_files;
2675 unsigned num_unsaved_files;
2676 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002677 CXTranslationUnit *out_TU;
2678 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002679};
2680static void clang_parseTranslationUnit_Impl(void *UserData) {
2681 ParseTranslationUnitInfo *PTUI =
2682 static_cast<ParseTranslationUnitInfo*>(UserData);
2683 CXIndex CIdx = PTUI->CIdx;
2684 const char *source_filename = PTUI->source_filename;
2685 const char * const *command_line_args = PTUI->command_line_args;
2686 int num_command_line_args = PTUI->num_command_line_args;
2687 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2688 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2689 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002690 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002691
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002692 // Set up the initial return values.
2693 if (out_TU)
2694 *out_TU = NULL;
2695 PTUI->result = CXError_Failure;
2696
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002697 // Check arguments.
2698 if (!CIdx || !out_TU ||
2699 (unsaved_files == NULL && num_unsaved_files != 0)) {
2700 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002701 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002702 }
2703
Guy Benyei11169dd2012-12-18 14:30:41 +00002704 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2705
2706 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2707 setThreadBackgroundPriority();
2708
2709 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2710 // FIXME: Add a flag for modules.
2711 TranslationUnitKind TUKind
2712 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002713 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002714 = options & CXTranslationUnit_CacheCompletionResults;
2715 bool IncludeBriefCommentsInCodeCompletion
2716 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2717 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2718 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2719
2720 // Configure the diagnostics.
2721 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002722 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002723
2724 // Recover resources if we crash before exiting this function.
2725 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2726 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2727 DiagCleanup(Diags.getPtr());
2728
2729 OwningPtr<std::vector<ASTUnit::RemappedFile> >
2730 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
2731
2732 // Recover resources if we crash before exiting this function.
2733 llvm::CrashRecoveryContextCleanupRegistrar<
2734 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2735
2736 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2737 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2738 const llvm::MemoryBuffer *Buffer
2739 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2740 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2741 Buffer));
2742 }
2743
2744 OwningPtr<std::vector<const char *> >
2745 Args(new std::vector<const char*>());
2746
2747 // Recover resources if we crash before exiting this method.
2748 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2749 ArgsCleanup(Args.get());
2750
2751 // Since the Clang C library is primarily used by batch tools dealing with
2752 // (often very broken) source code, where spell-checking can have a
2753 // significant negative impact on performance (particularly when
2754 // precompiled headers are involved), we disable it by default.
2755 // Only do this if we haven't found a spell-checking-related argument.
2756 bool FoundSpellCheckingArgument = false;
2757 for (int I = 0; I != num_command_line_args; ++I) {
2758 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2759 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2760 FoundSpellCheckingArgument = true;
2761 break;
2762 }
2763 }
2764 if (!FoundSpellCheckingArgument)
2765 Args->push_back("-fno-spell-checking");
2766
2767 Args->insert(Args->end(), command_line_args,
2768 command_line_args + num_command_line_args);
2769
2770 // The 'source_filename' argument is optional. If the caller does not
2771 // specify it then it is assumed that the source file is specified
2772 // in the actual argument list.
2773 // Put the source file after command_line_args otherwise if '-x' flag is
2774 // present it will be unused.
2775 if (source_filename)
2776 Args->push_back(source_filename);
2777
2778 // Do we need the detailed preprocessing record?
2779 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2780 Args->push_back("-Xclang");
2781 Args->push_back("-detailed-preprocessing-record");
2782 }
2783
2784 unsigned NumErrors = Diags->getClient()->getNumErrors();
2785 OwningPtr<ASTUnit> ErrUnit;
2786 OwningPtr<ASTUnit> Unit(
2787 ASTUnit::LoadFromCommandLine(Args->size() ? &(*Args)[0] : 0
2788 /* vector::data() not portable */,
2789 Args->size() ? (&(*Args)[0] + Args->size()) :0,
2790 Diags,
2791 CXXIdx->getClangResourcesPath(),
2792 CXXIdx->getOnlyLocalDecls(),
2793 /*CaptureDiagnostics=*/true,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002794 *RemappedFiles.get(),
Guy Benyei11169dd2012-12-18 14:30:41 +00002795 /*RemappedFilesKeepOriginalName=*/true,
2796 PrecompilePreamble,
2797 TUKind,
Alp Toker8c8a8752013-12-03 06:53:35 +00002798 CacheCodeCompletionResults,
Guy Benyei11169dd2012-12-18 14:30:41 +00002799 IncludeBriefCommentsInCodeCompletion,
2800 /*AllowPCHWithCompilerErrors=*/true,
2801 SkipFunctionBodies,
2802 /*UserFilesAreVolatile=*/true,
2803 ForSerialization,
2804 &ErrUnit));
2805
2806 if (NumErrors != Diags->getClient()->getNumErrors()) {
2807 // Make sure to check that 'Unit' is non-NULL.
2808 if (CXXIdx->getDisplayDiagnostics())
2809 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2810 }
2811
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002812 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2813 PTUI->result = CXError_ASTReadError;
2814 } else {
2815 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.take());
2816 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2817 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002818}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002819
2820CXTranslationUnit
2821clang_parseTranslationUnit(CXIndex CIdx,
2822 const char *source_filename,
2823 const char *const *command_line_args,
2824 int num_command_line_args,
2825 struct CXUnsavedFile *unsaved_files,
2826 unsigned num_unsaved_files,
2827 unsigned options) {
2828 CXTranslationUnit TU;
2829 enum CXErrorCode Result = clang_parseTranslationUnit2(
2830 CIdx, source_filename, command_line_args, num_command_line_args,
2831 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002832 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002833 assert((TU && Result == CXError_Success) ||
2834 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002835 return TU;
2836}
2837
2838enum CXErrorCode clang_parseTranslationUnit2(
2839 CXIndex CIdx,
2840 const char *source_filename,
2841 const char *const *command_line_args,
2842 int num_command_line_args,
2843 struct CXUnsavedFile *unsaved_files,
2844 unsigned num_unsaved_files,
2845 unsigned options,
2846 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002847 LOG_FUNC_SECTION {
2848 *Log << source_filename << ": ";
2849 for (int i = 0; i != num_command_line_args; ++i)
2850 *Log << command_line_args[i] << " ";
2851 }
2852
Guy Benyei11169dd2012-12-18 14:30:41 +00002853 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2854 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002855 num_unsaved_files, options, out_TU,
2856 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002857 llvm::CrashRecoveryContext CRC;
2858
2859 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2860 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2861 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2862 fprintf(stderr, " 'command_line_args' : [");
2863 for (int i = 0; i != num_command_line_args; ++i) {
2864 if (i)
2865 fprintf(stderr, ", ");
2866 fprintf(stderr, "'%s'", command_line_args[i]);
2867 }
2868 fprintf(stderr, "],\n");
2869 fprintf(stderr, " 'unsaved_files' : [");
2870 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2871 if (i)
2872 fprintf(stderr, ", ");
2873 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2874 unsaved_files[i].Length);
2875 }
2876 fprintf(stderr, "],\n");
2877 fprintf(stderr, " 'options' : %d,\n", options);
2878 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002879
2880 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002881 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002882 if (CXTranslationUnit *TU = PTUI.out_TU)
2883 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002884 }
2885
2886 return PTUI.result;
2887}
2888
2889unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2890 return CXSaveTranslationUnit_None;
2891}
2892
2893namespace {
2894
2895struct SaveTranslationUnitInfo {
2896 CXTranslationUnit TU;
2897 const char *FileName;
2898 unsigned options;
2899 CXSaveError result;
2900};
2901
2902}
2903
2904static void clang_saveTranslationUnit_Impl(void *UserData) {
2905 SaveTranslationUnitInfo *STUI =
2906 static_cast<SaveTranslationUnitInfo*>(UserData);
2907
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002908 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002909 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2910 setThreadBackgroundPriority();
2911
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002912 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002913 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2914}
2915
2916int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2917 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002918 LOG_FUNC_SECTION {
2919 *Log << TU << ' ' << FileName;
2920 }
2921
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002922 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002923 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002924 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002925 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002926
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002927 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002928 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2929 if (!CXXUnit->hasSema())
2930 return CXSaveError_InvalidTU;
2931
2932 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2933
2934 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2935 getenv("LIBCLANG_NOTHREADS")) {
2936 clang_saveTranslationUnit_Impl(&STUI);
2937
2938 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2939 PrintLibclangResourceUsage(TU);
2940
2941 return STUI.result;
2942 }
2943
2944 // We have an AST that has invalid nodes due to compiler errors.
2945 // Use a crash recovery thread for protection.
2946
2947 llvm::CrashRecoveryContext CRC;
2948
2949 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2950 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2951 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2952 fprintf(stderr, " 'options' : %d,\n", options);
2953 fprintf(stderr, "}\n");
2954
2955 return CXSaveError_Unknown;
2956
2957 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2958 PrintLibclangResourceUsage(TU);
2959 }
2960
2961 return STUI.result;
2962}
2963
2964void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2965 if (CTUnit) {
2966 // If the translation unit has been marked as unsafe to free, just discard
2967 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002968 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2969 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002970 return;
2971
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002972 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002973 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002974 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2975 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002976 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002977 delete CTUnit;
2978 }
2979}
2980
2981unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2982 return CXReparse_None;
2983}
2984
2985struct ReparseTranslationUnitInfo {
2986 CXTranslationUnit TU;
2987 unsigned num_unsaved_files;
2988 struct CXUnsavedFile *unsaved_files;
2989 unsigned options;
2990 int result;
2991};
2992
2993static void clang_reparseTranslationUnit_Impl(void *UserData) {
2994 ReparseTranslationUnitInfo *RTUI =
2995 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002996 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002997
Guy Benyei11169dd2012-12-18 14:30:41 +00002998 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002999 unsigned num_unsaved_files = RTUI->num_unsaved_files;
3000 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
3001 unsigned options = RTUI->options;
3002 (void) options;
3003
3004 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003005 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003006 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003007 RTUI->result = CXError_InvalidArguments;
3008 return;
3009 }
3010 if (unsaved_files == NULL && num_unsaved_files != 0) {
3011 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003012 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003013 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003014
3015 // Reset the associated diagnostics.
3016 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3017 TU->Diagnostics = 0;
3018
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003019 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003020 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3021 setThreadBackgroundPriority();
3022
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003023 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003024 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
3025
3026 OwningPtr<std::vector<ASTUnit::RemappedFile> >
3027 RemappedFiles(new std::vector<ASTUnit::RemappedFile>());
3028
3029 // Recover resources if we crash before exiting this function.
3030 llvm::CrashRecoveryContextCleanupRegistrar<
3031 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3032
3033 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3034 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3035 const llvm::MemoryBuffer *Buffer
3036 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3037 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3038 Buffer));
3039 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003040
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003041 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003042 RTUI->result = CXError_Success;
3043 else if (isASTReadError(CXXUnit))
3044 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003045}
3046
3047int clang_reparseTranslationUnit(CXTranslationUnit TU,
3048 unsigned num_unsaved_files,
3049 struct CXUnsavedFile *unsaved_files,
3050 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003051 LOG_FUNC_SECTION {
3052 *Log << TU;
3053 }
3054
Guy Benyei11169dd2012-12-18 14:30:41 +00003055 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003056 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003057
3058 if (getenv("LIBCLANG_NOTHREADS")) {
3059 clang_reparseTranslationUnit_Impl(&RTUI);
3060 return RTUI.result;
3061 }
3062
3063 llvm::CrashRecoveryContext CRC;
3064
3065 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3066 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003067 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003068 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003069 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3070 PrintLibclangResourceUsage(TU);
3071
3072 return RTUI.result;
3073}
3074
3075
3076CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003077 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003078 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003079 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003080 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003081
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003082 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003083 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003084}
3085
3086CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003087 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003088 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003089 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003090 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003091
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003092 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003093 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3094}
3095
3096} // end: extern "C"
3097
3098//===----------------------------------------------------------------------===//
3099// CXFile Operations.
3100//===----------------------------------------------------------------------===//
3101
3102extern "C" {
3103CXString clang_getFileName(CXFile SFile) {
3104 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003105 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003106
3107 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003108 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003109}
3110
3111time_t clang_getFileTime(CXFile SFile) {
3112 if (!SFile)
3113 return 0;
3114
3115 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3116 return FEnt->getModificationTime();
3117}
3118
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003119CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003120 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003121 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003122 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003123 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003124
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003125 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003126
3127 FileManager &FMgr = CXXUnit->getFileManager();
3128 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3129}
3130
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003131unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3132 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003133 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003134 LOG_BAD_TU(TU);
3135 return 0;
3136 }
3137
3138 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003139 return 0;
3140
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003141 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003142 FileEntry *FEnt = static_cast<FileEntry *>(file);
3143 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3144 .isFileMultipleIncludeGuarded(FEnt);
3145}
3146
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003147int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3148 if (!file || !outID)
3149 return 1;
3150
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003151 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003152 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3153 outID->data[0] = ID.getDevice();
3154 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003155 outID->data[2] = FEnt->getModificationTime();
3156 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003157}
3158
Guy Benyei11169dd2012-12-18 14:30:41 +00003159} // end: extern "C"
3160
3161//===----------------------------------------------------------------------===//
3162// CXCursor Operations.
3163//===----------------------------------------------------------------------===//
3164
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003165static const Decl *getDeclFromExpr(const Stmt *E) {
3166 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003167 return getDeclFromExpr(CE->getSubExpr());
3168
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003169 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003170 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003171 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003172 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003173 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003174 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003175 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003176 if (PRE->isExplicitProperty())
3177 return PRE->getExplicitProperty();
3178 // It could be messaging both getter and setter as in:
3179 // ++myobj.myprop;
3180 // in which case prefer to associate the setter since it is less obvious
3181 // from inspecting the source that the setter is going to get called.
3182 if (PRE->isMessagingSetter())
3183 return PRE->getImplicitPropertySetter();
3184 return PRE->getImplicitPropertyGetter();
3185 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003186 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003187 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003188 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003189 if (Expr *Src = OVE->getSourceExpr())
3190 return getDeclFromExpr(Src);
3191
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003192 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003193 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003194 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003195 if (!CE->isElidable())
3196 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003197 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003198 return OME->getMethodDecl();
3199
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003200 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003201 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003202 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003203 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3204 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003205 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003206 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3207 isa<ParmVarDecl>(SizeOfPack->getPack()))
3208 return SizeOfPack->getPack();
3209
3210 return 0;
3211}
3212
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003213static SourceLocation getLocationFromExpr(const Expr *E) {
3214 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003215 return getLocationFromExpr(CE->getSubExpr());
3216
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003217 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003218 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003219 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003220 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003221 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003222 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003223 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003224 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003225 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003226 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003227 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003228 return PropRef->getLocation();
3229
3230 return E->getLocStart();
3231}
3232
3233extern "C" {
3234
3235unsigned clang_visitChildren(CXCursor parent,
3236 CXCursorVisitor visitor,
3237 CXClientData client_data) {
3238 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3239 /*VisitPreprocessorLast=*/false);
3240 return CursorVis.VisitChildren(parent);
3241}
3242
3243#ifndef __has_feature
3244#define __has_feature(x) 0
3245#endif
3246#if __has_feature(blocks)
3247typedef enum CXChildVisitResult
3248 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3249
3250static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3251 CXClientData client_data) {
3252 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3253 return block(cursor, parent);
3254}
3255#else
3256// If we are compiled with a compiler that doesn't have native blocks support,
3257// define and call the block manually, so the
3258typedef struct _CXChildVisitResult
3259{
3260 void *isa;
3261 int flags;
3262 int reserved;
3263 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3264 CXCursor);
3265} *CXCursorVisitorBlock;
3266
3267static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3268 CXClientData client_data) {
3269 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3270 return block->invoke(block, cursor, parent);
3271}
3272#endif
3273
3274
3275unsigned clang_visitChildrenWithBlock(CXCursor parent,
3276 CXCursorVisitorBlock block) {
3277 return clang_visitChildren(parent, visitWithBlock, block);
3278}
3279
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003280static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003281 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003282 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003283
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003284 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003285 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003286 if (const ObjCPropertyImplDecl *PropImpl =
3287 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003288 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003289 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003290
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003291 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003292 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003293 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003294
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003295 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003296 }
3297
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003298 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003299 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003300
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003301 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003302 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3303 // and returns different names. NamedDecl returns the class name and
3304 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003305 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003306
3307 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003308 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003309
3310 SmallString<1024> S;
3311 llvm::raw_svector_ostream os(S);
3312 ND->printName(os);
3313
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003314 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003315}
3316
3317CXString clang_getCursorSpelling(CXCursor C) {
3318 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003319 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003320
3321 if (clang_isReference(C.kind)) {
3322 switch (C.kind) {
3323 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003324 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003325 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003326 }
3327 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003328 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003329 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003330 }
3331 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003332 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003333 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003334 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003335 }
3336 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003337 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003338 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003339 }
3340 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003341 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003342 assert(Type && "Missing type decl");
3343
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003344 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003345 getAsString());
3346 }
3347 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003348 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003349 assert(Template && "Missing template decl");
3350
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003351 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003352 }
3353
3354 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003355 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003356 assert(NS && "Missing namespace decl");
3357
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003358 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003359 }
3360
3361 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003362 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003363 assert(Field && "Missing member decl");
3364
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003365 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003366 }
3367
3368 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003369 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003370 assert(Label && "Missing label");
3371
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003372 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 }
3374
3375 case CXCursor_OverloadedDeclRef: {
3376 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003377 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3378 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003379 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003380 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003381 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003382 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003383 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 OverloadedTemplateStorage *Ovl
3385 = Storage.get<OverloadedTemplateStorage*>();
3386 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003387 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003388 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003389 }
3390
3391 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003392 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003393 assert(Var && "Missing variable decl");
3394
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003395 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003396 }
3397
3398 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003399 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003400 }
3401 }
3402
3403 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003404 const Expr *E = getCursorExpr(C);
3405
3406 if (C.kind == CXCursor_ObjCStringLiteral ||
3407 C.kind == CXCursor_StringLiteral) {
3408 const StringLiteral *SLit;
3409 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3410 SLit = OSL->getString();
3411 } else {
3412 SLit = cast<StringLiteral>(E);
3413 }
3414 SmallString<256> Buf;
3415 llvm::raw_svector_ostream OS(Buf);
3416 SLit->outputString(OS);
3417 return cxstring::createDup(OS.str());
3418 }
3419
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003420 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003421 if (D)
3422 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003423 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003424 }
3425
3426 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003427 const Stmt *S = getCursorStmt(C);
3428 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003429 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003430
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003431 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003432 }
3433
3434 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003435 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003436 ->getNameStart());
3437
3438 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003439 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003440 ->getNameStart());
3441
3442 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003443 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003444
3445 if (clang_isDeclaration(C.kind))
3446 return getDeclSpelling(getCursorDecl(C));
3447
3448 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003449 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003450 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003451 }
3452
3453 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003454 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003455 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003456 }
3457
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003458 if (C.kind == CXCursor_PackedAttr) {
3459 return cxstring::createRef("packed");
3460 }
3461
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003462 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003463}
3464
3465CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3466 unsigned pieceIndex,
3467 unsigned options) {
3468 if (clang_Cursor_isNull(C))
3469 return clang_getNullRange();
3470
3471 ASTContext &Ctx = getCursorContext(C);
3472
3473 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003474 const Stmt *S = getCursorStmt(C);
3475 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003476 if (pieceIndex > 0)
3477 return clang_getNullRange();
3478 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3479 }
3480
3481 return clang_getNullRange();
3482 }
3483
3484 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003485 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003486 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3487 if (pieceIndex >= ME->getNumSelectorLocs())
3488 return clang_getNullRange();
3489 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3490 }
3491 }
3492
3493 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3494 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003495 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003496 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3497 if (pieceIndex >= MD->getNumSelectorLocs())
3498 return clang_getNullRange();
3499 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3500 }
3501 }
3502
3503 if (C.kind == CXCursor_ObjCCategoryDecl ||
3504 C.kind == CXCursor_ObjCCategoryImplDecl) {
3505 if (pieceIndex > 0)
3506 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003507 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003508 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3509 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003510 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3512 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3513 }
3514
3515 if (C.kind == CXCursor_ModuleImportDecl) {
3516 if (pieceIndex > 0)
3517 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003518 if (const ImportDecl *ImportD =
3519 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003520 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3521 if (!Locs.empty())
3522 return cxloc::translateSourceRange(Ctx,
3523 SourceRange(Locs.front(), Locs.back()));
3524 }
3525 return clang_getNullRange();
3526 }
3527
3528 // FIXME: A CXCursor_InclusionDirective should give the location of the
3529 // filename, but we don't keep track of this.
3530
3531 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3532 // but we don't keep track of this.
3533
3534 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3535 // but we don't keep track of this.
3536
3537 // Default handling, give the location of the cursor.
3538
3539 if (pieceIndex > 0)
3540 return clang_getNullRange();
3541
3542 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3543 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3544 return cxloc::translateSourceRange(Ctx, Loc);
3545}
3546
3547CXString clang_getCursorDisplayName(CXCursor C) {
3548 if (!clang_isDeclaration(C.kind))
3549 return clang_getCursorSpelling(C);
3550
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003551 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003552 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003553 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003554
3555 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003556 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003557 D = FunTmpl->getTemplatedDecl();
3558
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003559 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003560 SmallString<64> Str;
3561 llvm::raw_svector_ostream OS(Str);
3562 OS << *Function;
3563 if (Function->getPrimaryTemplate())
3564 OS << "<>";
3565 OS << "(";
3566 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3567 if (I)
3568 OS << ", ";
3569 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3570 }
3571
3572 if (Function->isVariadic()) {
3573 if (Function->getNumParams())
3574 OS << ", ";
3575 OS << "...";
3576 }
3577 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003578 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003579 }
3580
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003581 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003582 SmallString<64> Str;
3583 llvm::raw_svector_ostream OS(Str);
3584 OS << *ClassTemplate;
3585 OS << "<";
3586 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3587 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3588 if (I)
3589 OS << ", ";
3590
3591 NamedDecl *Param = Params->getParam(I);
3592 if (Param->getIdentifier()) {
3593 OS << Param->getIdentifier()->getName();
3594 continue;
3595 }
3596
3597 // There is no parameter name, which makes this tricky. Try to come up
3598 // with something useful that isn't too long.
3599 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3600 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3601 else if (NonTypeTemplateParmDecl *NTTP
3602 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3603 OS << NTTP->getType().getAsString(Policy);
3604 else
3605 OS << "template<...> class";
3606 }
3607
3608 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003609 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 }
3611
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003612 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003613 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3614 // If the type was explicitly written, use that.
3615 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003616 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003617
Benjamin Kramer9170e912013-02-22 15:46:01 +00003618 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003619 llvm::raw_svector_ostream OS(Str);
3620 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003621 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003622 ClassSpec->getTemplateArgs().data(),
3623 ClassSpec->getTemplateArgs().size(),
3624 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003625 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003626 }
3627
3628 return clang_getCursorSpelling(C);
3629}
3630
3631CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3632 switch (Kind) {
3633 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003634 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003635 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003636 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003637 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003638 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003639 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003640 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003641 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003642 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003643 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003644 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003645 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003646 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003647 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003648 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003649 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003650 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003651 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003652 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003653 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003654 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003655 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003656 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003657 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003658 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003659 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003660 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003661 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003662 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003663 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003664 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003665 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003666 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003667 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003668 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003669 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003670 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003671 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003672 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003673 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003674 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003675 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003676 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003677 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003678 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003679 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003680 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003681 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003682 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003683 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003684 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003685 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003686 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003687 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003688 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003689 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003690 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003691 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003692 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003693 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003694 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003695 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003696 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003697 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003698 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003699 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003700 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003701 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003702 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003703 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003704 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003705 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003706 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003707 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003708 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003709 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003710 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003711 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003712 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003713 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003714 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003715 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003716 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003717 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003718 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003719 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003720 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003721 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003722 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003723 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003724 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003725 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003726 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003727 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003728 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003729 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003730 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003731 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003732 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003733 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003734 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003735 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003736 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003737 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003738 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003739 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003740 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003741 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003742 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003743 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003744 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003745 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003746 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003747 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003748 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003749 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003750 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003751 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003752 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003753 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003754 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003755 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003756 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003757 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003758 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003759 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003760 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003761 case CXCursor_ObjCSelfExpr:
3762 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003763 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003764 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003765 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003766 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003767 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003768 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003769 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003770 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003771 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003772 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003773 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003774 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003775 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003776 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003777 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003778 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003779 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003780 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003781 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003782 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003783 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003784 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003785 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003786 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003787 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003788 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003789 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003790 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003791 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003792 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003793 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003794 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003795 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003796 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003797 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003798 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003799 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003800 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003801 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003802 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003803 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003804 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003805 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003806 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003807 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003808 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003809 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003810 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003811 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003812 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003813 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003814 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003815 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003816 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003817 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003818 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003819 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003820 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003821 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003822 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003823 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003824 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003825 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003826 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003827 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003828 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003829 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003830 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003831 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003832 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003833 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003834 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003835 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003836 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003837 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003838 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003839 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003840 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003841 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003842 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003843 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003844 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003845 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003846 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003847 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003848 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003849 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003850 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003851 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003852 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003853 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003854 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003855 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003856 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003857 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003858 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003859 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003860 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003861 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003862 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003863 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003864 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003865 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003866 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003867 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003868 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003869 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003870 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003871 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003872 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003873 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003874 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003875 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003876 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003877 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003878 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003879 case CXCursor_PackedAttr:
3880 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003881 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003882 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003883 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003884 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003885 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003886 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003887 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003888 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003889 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003890 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003891 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003892 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003893 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003894 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003895 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003896 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003897 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003898 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003899 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003900 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003901 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003902 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003903 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003904 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003905 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003906 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003907 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003908 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003909 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003910 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003911 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003912 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003913 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003914 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003915 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003916 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003917 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003918 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003919 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003920 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003921 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003922 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003923 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003924 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003925 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003926 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003927 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003928 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003929 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003930 return cxstring::createRef("OMPParallelDirective");
3931 case CXCursor_OMPSimdDirective:
3932 return cxstring::createRef("OMPSimdDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003933 }
3934
3935 llvm_unreachable("Unhandled CXCursorKind");
3936}
3937
3938struct GetCursorData {
3939 SourceLocation TokenBeginLoc;
3940 bool PointsAtMacroArgExpansion;
3941 bool VisitedObjCPropertyImplDecl;
3942 SourceLocation VisitedDeclaratorDeclStartLoc;
3943 CXCursor &BestCursor;
3944
3945 GetCursorData(SourceManager &SM,
3946 SourceLocation tokenBegin, CXCursor &outputCursor)
3947 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3948 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3949 VisitedObjCPropertyImplDecl = false;
3950 }
3951};
3952
3953static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3954 CXCursor parent,
3955 CXClientData client_data) {
3956 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3957 CXCursor *BestCursor = &Data->BestCursor;
3958
3959 // If we point inside a macro argument we should provide info of what the
3960 // token is so use the actual cursor, don't replace it with a macro expansion
3961 // cursor.
3962 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3963 return CXChildVisit_Recurse;
3964
3965 if (clang_isDeclaration(cursor.kind)) {
3966 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003967 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3969 if (MD->isImplicit())
3970 return CXChildVisit_Break;
3971
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003972 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003973 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3974 // Check that when we have multiple @class references in the same line,
3975 // that later ones do not override the previous ones.
3976 // If we have:
3977 // @class Foo, Bar;
3978 // source ranges for both start at '@', so 'Bar' will end up overriding
3979 // 'Foo' even though the cursor location was at 'Foo'.
3980 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3981 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003982 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003983 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3984 if (PrevID != ID &&
3985 !PrevID->isThisDeclarationADefinition() &&
3986 !ID->isThisDeclarationADefinition())
3987 return CXChildVisit_Break;
3988 }
3989
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003990 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003991 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3992 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3993 // Check that when we have multiple declarators in the same line,
3994 // that later ones do not override the previous ones.
3995 // If we have:
3996 // int Foo, Bar;
3997 // source ranges for both start at 'int', so 'Bar' will end up overriding
3998 // 'Foo' even though the cursor location was at 'Foo'.
3999 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4000 return CXChildVisit_Break;
4001 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4002
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004003 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4005 (void)PropImp;
4006 // Check that when we have multiple @synthesize in the same line,
4007 // that later ones do not override the previous ones.
4008 // If we have:
4009 // @synthesize Foo, Bar;
4010 // source ranges for both start at '@', so 'Bar' will end up overriding
4011 // 'Foo' even though the cursor location was at 'Foo'.
4012 if (Data->VisitedObjCPropertyImplDecl)
4013 return CXChildVisit_Break;
4014 Data->VisitedObjCPropertyImplDecl = true;
4015 }
4016 }
4017
4018 if (clang_isExpression(cursor.kind) &&
4019 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004020 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004021 // Avoid having the cursor of an expression replace the declaration cursor
4022 // when the expression source range overlaps the declaration range.
4023 // This can happen for C++ constructor expressions whose range generally
4024 // include the variable declaration, e.g.:
4025 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4026 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4027 D->getLocation() == Data->TokenBeginLoc)
4028 return CXChildVisit_Break;
4029 }
4030 }
4031
4032 // If our current best cursor is the construction of a temporary object,
4033 // don't replace that cursor with a type reference, because we want
4034 // clang_getCursor() to point at the constructor.
4035 if (clang_isExpression(BestCursor->kind) &&
4036 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4037 cursor.kind == CXCursor_TypeRef) {
4038 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4039 // as having the actual point on the type reference.
4040 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4041 return CXChildVisit_Recurse;
4042 }
4043
4044 *BestCursor = cursor;
4045 return CXChildVisit_Recurse;
4046}
4047
4048CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004049 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004050 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004051 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004052 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004053
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004054 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004055 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4056
4057 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4058 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4059
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004060 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004061 CXFile SearchFile;
4062 unsigned SearchLine, SearchColumn;
4063 CXFile ResultFile;
4064 unsigned ResultLine, ResultColumn;
4065 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4066 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4067 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4068
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004069 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4070 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 &ResultColumn, 0);
4072 SearchFileName = clang_getFileName(SearchFile);
4073 ResultFileName = clang_getFileName(ResultFile);
4074 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4075 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004076 *Log << llvm::format("(%s:%d:%d) = %s",
4077 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4078 clang_getCString(KindSpelling))
4079 << llvm::format("(%s:%d:%d):%s%s",
4080 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4081 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004082 clang_disposeString(SearchFileName);
4083 clang_disposeString(ResultFileName);
4084 clang_disposeString(KindSpelling);
4085 clang_disposeString(USR);
4086
4087 CXCursor Definition = clang_getCursorDefinition(Result);
4088 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4089 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4090 CXString DefinitionKindSpelling
4091 = clang_getCursorKindSpelling(Definition.kind);
4092 CXFile DefinitionFile;
4093 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004094 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 &DefinitionLine, &DefinitionColumn, 0);
4096 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004097 *Log << llvm::format(" -> %s(%s:%d:%d)",
4098 clang_getCString(DefinitionKindSpelling),
4099 clang_getCString(DefinitionFileName),
4100 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004101 clang_disposeString(DefinitionFileName);
4102 clang_disposeString(DefinitionKindSpelling);
4103 }
4104 }
4105
4106 return Result;
4107}
4108
4109CXCursor clang_getNullCursor(void) {
4110 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4111}
4112
4113unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004114 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4115 // can't set consistently. For example, when visiting a DeclStmt we will set
4116 // it but we don't set it on the result of clang_getCursorDefinition for
4117 // a reference of the same declaration.
4118 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4119 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4120 // to provide that kind of info.
4121 if (clang_isDeclaration(X.kind))
4122 X.data[1] = 0;
4123 if (clang_isDeclaration(Y.kind))
4124 Y.data[1] = 0;
4125
Guy Benyei11169dd2012-12-18 14:30:41 +00004126 return X == Y;
4127}
4128
4129unsigned clang_hashCursor(CXCursor C) {
4130 unsigned Index = 0;
4131 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4132 Index = 1;
4133
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004134 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004135 std::make_pair(C.kind, C.data[Index]));
4136}
4137
4138unsigned clang_isInvalid(enum CXCursorKind K) {
4139 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4140}
4141
4142unsigned clang_isDeclaration(enum CXCursorKind K) {
4143 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4144 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4145}
4146
4147unsigned clang_isReference(enum CXCursorKind K) {
4148 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4149}
4150
4151unsigned clang_isExpression(enum CXCursorKind K) {
4152 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4153}
4154
4155unsigned clang_isStatement(enum CXCursorKind K) {
4156 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4157}
4158
4159unsigned clang_isAttribute(enum CXCursorKind K) {
4160 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4161}
4162
4163unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4164 return K == CXCursor_TranslationUnit;
4165}
4166
4167unsigned clang_isPreprocessing(enum CXCursorKind K) {
4168 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4169}
4170
4171unsigned clang_isUnexposed(enum CXCursorKind K) {
4172 switch (K) {
4173 case CXCursor_UnexposedDecl:
4174 case CXCursor_UnexposedExpr:
4175 case CXCursor_UnexposedStmt:
4176 case CXCursor_UnexposedAttr:
4177 return true;
4178 default:
4179 return false;
4180 }
4181}
4182
4183CXCursorKind clang_getCursorKind(CXCursor C) {
4184 return C.kind;
4185}
4186
4187CXSourceLocation clang_getCursorLocation(CXCursor C) {
4188 if (clang_isReference(C.kind)) {
4189 switch (C.kind) {
4190 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004191 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004192 = getCursorObjCSuperClassRef(C);
4193 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4194 }
4195
4196 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004197 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004198 = getCursorObjCProtocolRef(C);
4199 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4200 }
4201
4202 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004203 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004204 = getCursorObjCClassRef(C);
4205 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4206 }
4207
4208 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004209 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4211 }
4212
4213 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004214 std::pair<const TemplateDecl *, SourceLocation> P =
4215 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4217 }
4218
4219 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004220 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004221 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4222 }
4223
4224 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004225 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004226 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4227 }
4228
4229 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004230 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004231 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4232 }
4233
4234 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004235 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004236 if (!BaseSpec)
4237 return clang_getNullLocation();
4238
4239 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4240 return cxloc::translateSourceLocation(getCursorContext(C),
4241 TSInfo->getTypeLoc().getBeginLoc());
4242
4243 return cxloc::translateSourceLocation(getCursorContext(C),
4244 BaseSpec->getLocStart());
4245 }
4246
4247 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004248 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004249 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4250 }
4251
4252 case CXCursor_OverloadedDeclRef:
4253 return cxloc::translateSourceLocation(getCursorContext(C),
4254 getCursorOverloadedDeclRef(C).second);
4255
4256 default:
4257 // FIXME: Need a way to enumerate all non-reference cases.
4258 llvm_unreachable("Missed a reference kind");
4259 }
4260 }
4261
4262 if (clang_isExpression(C.kind))
4263 return cxloc::translateSourceLocation(getCursorContext(C),
4264 getLocationFromExpr(getCursorExpr(C)));
4265
4266 if (clang_isStatement(C.kind))
4267 return cxloc::translateSourceLocation(getCursorContext(C),
4268 getCursorStmt(C)->getLocStart());
4269
4270 if (C.kind == CXCursor_PreprocessingDirective) {
4271 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4272 return cxloc::translateSourceLocation(getCursorContext(C), L);
4273 }
4274
4275 if (C.kind == CXCursor_MacroExpansion) {
4276 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004277 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004278 return cxloc::translateSourceLocation(getCursorContext(C), L);
4279 }
4280
4281 if (C.kind == CXCursor_MacroDefinition) {
4282 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4283 return cxloc::translateSourceLocation(getCursorContext(C), L);
4284 }
4285
4286 if (C.kind == CXCursor_InclusionDirective) {
4287 SourceLocation L
4288 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4289 return cxloc::translateSourceLocation(getCursorContext(C), L);
4290 }
4291
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004292 if (clang_isAttribute(C.kind)) {
4293 SourceLocation L
4294 = cxcursor::getCursorAttr(C)->getLocation();
4295 return cxloc::translateSourceLocation(getCursorContext(C), L);
4296 }
4297
Guy Benyei11169dd2012-12-18 14:30:41 +00004298 if (!clang_isDeclaration(C.kind))
4299 return clang_getNullLocation();
4300
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004301 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004302 if (!D)
4303 return clang_getNullLocation();
4304
4305 SourceLocation Loc = D->getLocation();
4306 // FIXME: Multiple variables declared in a single declaration
4307 // currently lack the information needed to correctly determine their
4308 // ranges when accounting for the type-specifier. We use context
4309 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4310 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004311 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004312 if (!cxcursor::isFirstInDeclGroup(C))
4313 Loc = VD->getLocation();
4314 }
4315
4316 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004317 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004318 Loc = MD->getSelectorStartLoc();
4319
4320 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4321}
4322
4323} // end extern "C"
4324
4325CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4326 assert(TU);
4327
4328 // Guard against an invalid SourceLocation, or we may assert in one
4329 // of the following calls.
4330 if (SLoc.isInvalid())
4331 return clang_getNullCursor();
4332
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004333 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004334
4335 // Translate the given source location to make it point at the beginning of
4336 // the token under the cursor.
4337 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4338 CXXUnit->getASTContext().getLangOpts());
4339
4340 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4341 if (SLoc.isValid()) {
4342 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4343 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4344 /*VisitPreprocessorLast=*/true,
4345 /*VisitIncludedEntities=*/false,
4346 SourceLocation(SLoc));
4347 CursorVis.visitFileRegion();
4348 }
4349
4350 return Result;
4351}
4352
4353static SourceRange getRawCursorExtent(CXCursor C) {
4354 if (clang_isReference(C.kind)) {
4355 switch (C.kind) {
4356 case CXCursor_ObjCSuperClassRef:
4357 return getCursorObjCSuperClassRef(C).second;
4358
4359 case CXCursor_ObjCProtocolRef:
4360 return getCursorObjCProtocolRef(C).second;
4361
4362 case CXCursor_ObjCClassRef:
4363 return getCursorObjCClassRef(C).second;
4364
4365 case CXCursor_TypeRef:
4366 return getCursorTypeRef(C).second;
4367
4368 case CXCursor_TemplateRef:
4369 return getCursorTemplateRef(C).second;
4370
4371 case CXCursor_NamespaceRef:
4372 return getCursorNamespaceRef(C).second;
4373
4374 case CXCursor_MemberRef:
4375 return getCursorMemberRef(C).second;
4376
4377 case CXCursor_CXXBaseSpecifier:
4378 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4379
4380 case CXCursor_LabelRef:
4381 return getCursorLabelRef(C).second;
4382
4383 case CXCursor_OverloadedDeclRef:
4384 return getCursorOverloadedDeclRef(C).second;
4385
4386 case CXCursor_VariableRef:
4387 return getCursorVariableRef(C).second;
4388
4389 default:
4390 // FIXME: Need a way to enumerate all non-reference cases.
4391 llvm_unreachable("Missed a reference kind");
4392 }
4393 }
4394
4395 if (clang_isExpression(C.kind))
4396 return getCursorExpr(C)->getSourceRange();
4397
4398 if (clang_isStatement(C.kind))
4399 return getCursorStmt(C)->getSourceRange();
4400
4401 if (clang_isAttribute(C.kind))
4402 return getCursorAttr(C)->getRange();
4403
4404 if (C.kind == CXCursor_PreprocessingDirective)
4405 return cxcursor::getCursorPreprocessingDirective(C);
4406
4407 if (C.kind == CXCursor_MacroExpansion) {
4408 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004409 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004410 return TU->mapRangeFromPreamble(Range);
4411 }
4412
4413 if (C.kind == CXCursor_MacroDefinition) {
4414 ASTUnit *TU = getCursorASTUnit(C);
4415 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4416 return TU->mapRangeFromPreamble(Range);
4417 }
4418
4419 if (C.kind == CXCursor_InclusionDirective) {
4420 ASTUnit *TU = getCursorASTUnit(C);
4421 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4422 return TU->mapRangeFromPreamble(Range);
4423 }
4424
4425 if (C.kind == CXCursor_TranslationUnit) {
4426 ASTUnit *TU = getCursorASTUnit(C);
4427 FileID MainID = TU->getSourceManager().getMainFileID();
4428 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4429 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4430 return SourceRange(Start, End);
4431 }
4432
4433 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004434 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004435 if (!D)
4436 return SourceRange();
4437
4438 SourceRange R = D->getSourceRange();
4439 // FIXME: Multiple variables declared in a single declaration
4440 // currently lack the information needed to correctly determine their
4441 // ranges when accounting for the type-specifier. We use context
4442 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4443 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004444 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004445 if (!cxcursor::isFirstInDeclGroup(C))
4446 R.setBegin(VD->getLocation());
4447 }
4448 return R;
4449 }
4450 return SourceRange();
4451}
4452
4453/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4454/// the decl-specifier-seq for declarations.
4455static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4456 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004457 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004458 if (!D)
4459 return SourceRange();
4460
4461 SourceRange R = D->getSourceRange();
4462
4463 // Adjust the start of the location for declarations preceded by
4464 // declaration specifiers.
4465 SourceLocation StartLoc;
4466 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4467 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4468 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004469 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004470 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4471 StartLoc = TI->getTypeLoc().getLocStart();
4472 }
4473
4474 if (StartLoc.isValid() && R.getBegin().isValid() &&
4475 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4476 R.setBegin(StartLoc);
4477
4478 // FIXME: Multiple variables declared in a single declaration
4479 // currently lack the information needed to correctly determine their
4480 // ranges when accounting for the type-specifier. We use context
4481 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4482 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004483 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004484 if (!cxcursor::isFirstInDeclGroup(C))
4485 R.setBegin(VD->getLocation());
4486 }
4487
4488 return R;
4489 }
4490
4491 return getRawCursorExtent(C);
4492}
4493
4494extern "C" {
4495
4496CXSourceRange clang_getCursorExtent(CXCursor C) {
4497 SourceRange R = getRawCursorExtent(C);
4498 if (R.isInvalid())
4499 return clang_getNullRange();
4500
4501 return cxloc::translateSourceRange(getCursorContext(C), R);
4502}
4503
4504CXCursor clang_getCursorReferenced(CXCursor C) {
4505 if (clang_isInvalid(C.kind))
4506 return clang_getNullCursor();
4507
4508 CXTranslationUnit tu = getCursorTU(C);
4509 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004510 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004511 if (!D)
4512 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004513 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004514 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004515 if (const ObjCPropertyImplDecl *PropImpl =
4516 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004517 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4518 return MakeCXCursor(Property, tu);
4519
4520 return C;
4521 }
4522
4523 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004524 const Expr *E = getCursorExpr(C);
4525 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004526 if (D) {
4527 CXCursor declCursor = MakeCXCursor(D, tu);
4528 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4529 declCursor);
4530 return declCursor;
4531 }
4532
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004533 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004534 return MakeCursorOverloadedDeclRef(Ovl, tu);
4535
4536 return clang_getNullCursor();
4537 }
4538
4539 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004540 const Stmt *S = getCursorStmt(C);
4541 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004542 if (LabelDecl *label = Goto->getLabel())
4543 if (LabelStmt *labelS = label->getStmt())
4544 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4545
4546 return clang_getNullCursor();
4547 }
4548
4549 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004550 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004551 return MakeMacroDefinitionCursor(Def, tu);
4552 }
4553
4554 if (!clang_isReference(C.kind))
4555 return clang_getNullCursor();
4556
4557 switch (C.kind) {
4558 case CXCursor_ObjCSuperClassRef:
4559 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4560
4561 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004562 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4563 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004564 return MakeCXCursor(Def, tu);
4565
4566 return MakeCXCursor(Prot, tu);
4567 }
4568
4569 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004570 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4571 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004572 return MakeCXCursor(Def, tu);
4573
4574 return MakeCXCursor(Class, tu);
4575 }
4576
4577 case CXCursor_TypeRef:
4578 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4579
4580 case CXCursor_TemplateRef:
4581 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4582
4583 case CXCursor_NamespaceRef:
4584 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4585
4586 case CXCursor_MemberRef:
4587 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4588
4589 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004590 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004591 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4592 tu ));
4593 }
4594
4595 case CXCursor_LabelRef:
4596 // FIXME: We end up faking the "parent" declaration here because we
4597 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004598 return MakeCXCursor(getCursorLabelRef(C).first,
4599 cxtu::getASTUnit(tu)->getASTContext()
4600 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004601 tu);
4602
4603 case CXCursor_OverloadedDeclRef:
4604 return C;
4605
4606 case CXCursor_VariableRef:
4607 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4608
4609 default:
4610 // We would prefer to enumerate all non-reference cursor kinds here.
4611 llvm_unreachable("Unhandled reference cursor kind");
4612 }
4613}
4614
4615CXCursor clang_getCursorDefinition(CXCursor C) {
4616 if (clang_isInvalid(C.kind))
4617 return clang_getNullCursor();
4618
4619 CXTranslationUnit TU = getCursorTU(C);
4620
4621 bool WasReference = false;
4622 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4623 C = clang_getCursorReferenced(C);
4624 WasReference = true;
4625 }
4626
4627 if (C.kind == CXCursor_MacroExpansion)
4628 return clang_getCursorReferenced(C);
4629
4630 if (!clang_isDeclaration(C.kind))
4631 return clang_getNullCursor();
4632
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004633 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004634 if (!D)
4635 return clang_getNullCursor();
4636
4637 switch (D->getKind()) {
4638 // Declaration kinds that don't really separate the notions of
4639 // declaration and definition.
4640 case Decl::Namespace:
4641 case Decl::Typedef:
4642 case Decl::TypeAlias:
4643 case Decl::TypeAliasTemplate:
4644 case Decl::TemplateTypeParm:
4645 case Decl::EnumConstant:
4646 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004647 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004648 case Decl::IndirectField:
4649 case Decl::ObjCIvar:
4650 case Decl::ObjCAtDefsField:
4651 case Decl::ImplicitParam:
4652 case Decl::ParmVar:
4653 case Decl::NonTypeTemplateParm:
4654 case Decl::TemplateTemplateParm:
4655 case Decl::ObjCCategoryImpl:
4656 case Decl::ObjCImplementation:
4657 case Decl::AccessSpec:
4658 case Decl::LinkageSpec:
4659 case Decl::ObjCPropertyImpl:
4660 case Decl::FileScopeAsm:
4661 case Decl::StaticAssert:
4662 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004663 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004664 case Decl::Label: // FIXME: Is this right??
4665 case Decl::ClassScopeFunctionSpecialization:
4666 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004667 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004668 return C;
4669
4670 // Declaration kinds that don't make any sense here, but are
4671 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004672 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004673 case Decl::TranslationUnit:
4674 break;
4675
4676 // Declaration kinds for which the definition is not resolvable.
4677 case Decl::UnresolvedUsingTypename:
4678 case Decl::UnresolvedUsingValue:
4679 break;
4680
4681 case Decl::UsingDirective:
4682 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4683 TU);
4684
4685 case Decl::NamespaceAlias:
4686 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4687
4688 case Decl::Enum:
4689 case Decl::Record:
4690 case Decl::CXXRecord:
4691 case Decl::ClassTemplateSpecialization:
4692 case Decl::ClassTemplatePartialSpecialization:
4693 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4694 return MakeCXCursor(Def, TU);
4695 return clang_getNullCursor();
4696
4697 case Decl::Function:
4698 case Decl::CXXMethod:
4699 case Decl::CXXConstructor:
4700 case Decl::CXXDestructor:
4701 case Decl::CXXConversion: {
4702 const FunctionDecl *Def = 0;
4703 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004704 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004705 return clang_getNullCursor();
4706 }
4707
Larisse Voufo39a1e502013-08-06 01:03:05 +00004708 case Decl::Var:
4709 case Decl::VarTemplateSpecialization:
4710 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004711 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004712 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004713 return MakeCXCursor(Def, TU);
4714 return clang_getNullCursor();
4715 }
4716
4717 case Decl::FunctionTemplate: {
4718 const FunctionDecl *Def = 0;
4719 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4720 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4721 return clang_getNullCursor();
4722 }
4723
4724 case Decl::ClassTemplate: {
4725 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4726 ->getDefinition())
4727 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4728 TU);
4729 return clang_getNullCursor();
4730 }
4731
Larisse Voufo39a1e502013-08-06 01:03:05 +00004732 case Decl::VarTemplate: {
4733 if (VarDecl *Def =
4734 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4735 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4736 return clang_getNullCursor();
4737 }
4738
Guy Benyei11169dd2012-12-18 14:30:41 +00004739 case Decl::Using:
4740 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4741 D->getLocation(), TU);
4742
4743 case Decl::UsingShadow:
4744 return clang_getCursorDefinition(
4745 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4746 TU));
4747
4748 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004749 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004750 if (Method->isThisDeclarationADefinition())
4751 return C;
4752
4753 // Dig out the method definition in the associated
4754 // @implementation, if we have it.
4755 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004756 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004757 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4758 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4759 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4760 Method->isInstanceMethod()))
4761 if (Def->isThisDeclarationADefinition())
4762 return MakeCXCursor(Def, TU);
4763
4764 return clang_getNullCursor();
4765 }
4766
4767 case Decl::ObjCCategory:
4768 if (ObjCCategoryImplDecl *Impl
4769 = cast<ObjCCategoryDecl>(D)->getImplementation())
4770 return MakeCXCursor(Impl, TU);
4771 return clang_getNullCursor();
4772
4773 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004774 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004775 return MakeCXCursor(Def, TU);
4776 return clang_getNullCursor();
4777
4778 case Decl::ObjCInterface: {
4779 // There are two notions of a "definition" for an Objective-C
4780 // class: the interface and its implementation. When we resolved a
4781 // reference to an Objective-C class, produce the @interface as
4782 // the definition; when we were provided with the interface,
4783 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004784 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004785 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004786 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004787 return MakeCXCursor(Def, TU);
4788 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4789 return MakeCXCursor(Impl, TU);
4790 return clang_getNullCursor();
4791 }
4792
4793 case Decl::ObjCProperty:
4794 // FIXME: We don't really know where to find the
4795 // ObjCPropertyImplDecls that implement this property.
4796 return clang_getNullCursor();
4797
4798 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004799 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004800 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004801 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004802 return MakeCXCursor(Def, TU);
4803
4804 return clang_getNullCursor();
4805
4806 case Decl::Friend:
4807 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4808 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4809 return clang_getNullCursor();
4810
4811 case Decl::FriendTemplate:
4812 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4813 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4814 return clang_getNullCursor();
4815 }
4816
4817 return clang_getNullCursor();
4818}
4819
4820unsigned clang_isCursorDefinition(CXCursor C) {
4821 if (!clang_isDeclaration(C.kind))
4822 return 0;
4823
4824 return clang_getCursorDefinition(C) == C;
4825}
4826
4827CXCursor clang_getCanonicalCursor(CXCursor C) {
4828 if (!clang_isDeclaration(C.kind))
4829 return C;
4830
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004831 if (const Decl *D = getCursorDecl(C)) {
4832 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004833 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4834 return MakeCXCursor(CatD, getCursorTU(C));
4835
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004836 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4837 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004838 return MakeCXCursor(IFD, getCursorTU(C));
4839
4840 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4841 }
4842
4843 return C;
4844}
4845
4846int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4847 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4848}
4849
4850unsigned clang_getNumOverloadedDecls(CXCursor C) {
4851 if (C.kind != CXCursor_OverloadedDeclRef)
4852 return 0;
4853
4854 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004855 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004856 return E->getNumDecls();
4857
4858 if (OverloadedTemplateStorage *S
4859 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4860 return S->size();
4861
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004862 const Decl *D = Storage.get<const Decl *>();
4863 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004864 return Using->shadow_size();
4865
4866 return 0;
4867}
4868
4869CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4870 if (cursor.kind != CXCursor_OverloadedDeclRef)
4871 return clang_getNullCursor();
4872
4873 if (index >= clang_getNumOverloadedDecls(cursor))
4874 return clang_getNullCursor();
4875
4876 CXTranslationUnit TU = getCursorTU(cursor);
4877 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004878 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004879 return MakeCXCursor(E->decls_begin()[index], TU);
4880
4881 if (OverloadedTemplateStorage *S
4882 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4883 return MakeCXCursor(S->begin()[index], TU);
4884
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004885 const Decl *D = Storage.get<const Decl *>();
4886 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004887 // FIXME: This is, unfortunately, linear time.
4888 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4889 std::advance(Pos, index);
4890 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4891 }
4892
4893 return clang_getNullCursor();
4894}
4895
4896void clang_getDefinitionSpellingAndExtent(CXCursor C,
4897 const char **startBuf,
4898 const char **endBuf,
4899 unsigned *startLine,
4900 unsigned *startColumn,
4901 unsigned *endLine,
4902 unsigned *endColumn) {
4903 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004904 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004905 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4906
4907 SourceManager &SM = FD->getASTContext().getSourceManager();
4908 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4909 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4910 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4911 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4912 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4913 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4914}
4915
4916
4917CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4918 unsigned PieceIndex) {
4919 RefNamePieces Pieces;
4920
4921 switch (C.kind) {
4922 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004923 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004924 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4925 E->getQualifierLoc().getSourceRange());
4926 break;
4927
4928 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004929 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004930 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4931 E->getQualifierLoc().getSourceRange(),
4932 E->getOptionalExplicitTemplateArgs());
4933 break;
4934
4935 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004936 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004937 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004938 const Expr *Callee = OCE->getCallee();
4939 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004940 Callee = ICE->getSubExpr();
4941
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004942 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004943 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4944 DRE->getQualifierLoc().getSourceRange());
4945 }
4946 break;
4947
4948 default:
4949 break;
4950 }
4951
4952 if (Pieces.empty()) {
4953 if (PieceIndex == 0)
4954 return clang_getCursorExtent(C);
4955 } else if (PieceIndex < Pieces.size()) {
4956 SourceRange R = Pieces[PieceIndex];
4957 if (R.isValid())
4958 return cxloc::translateSourceRange(getCursorContext(C), R);
4959 }
4960
4961 return clang_getNullRange();
4962}
4963
4964void clang_enableStackTraces(void) {
4965 llvm::sys::PrintStackTraceOnErrorSignal();
4966}
4967
4968void clang_executeOnThread(void (*fn)(void*), void *user_data,
4969 unsigned stack_size) {
4970 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4971}
4972
4973} // end: extern "C"
4974
4975//===----------------------------------------------------------------------===//
4976// Token-based Operations.
4977//===----------------------------------------------------------------------===//
4978
4979/* CXToken layout:
4980 * int_data[0]: a CXTokenKind
4981 * int_data[1]: starting token location
4982 * int_data[2]: token length
4983 * int_data[3]: reserved
4984 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4985 * otherwise unused.
4986 */
4987extern "C" {
4988
4989CXTokenKind clang_getTokenKind(CXToken CXTok) {
4990 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4991}
4992
4993CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4994 switch (clang_getTokenKind(CXTok)) {
4995 case CXToken_Identifier:
4996 case CXToken_Keyword:
4997 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004998 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004999 ->getNameStart());
5000
5001 case CXToken_Literal: {
5002 // We have stashed the starting pointer in the ptr_data field. Use it.
5003 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005004 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005005 }
5006
5007 case CXToken_Punctuation:
5008 case CXToken_Comment:
5009 break;
5010 }
5011
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005012 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005013 LOG_BAD_TU(TU);
5014 return cxstring::createEmpty();
5015 }
5016
Guy Benyei11169dd2012-12-18 14:30:41 +00005017 // We have to find the starting buffer pointer the hard way, by
5018 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005019 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005020 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005021 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005022
5023 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5024 std::pair<FileID, unsigned> LocInfo
5025 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5026 bool Invalid = false;
5027 StringRef Buffer
5028 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5029 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005030 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005031
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005032 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005033}
5034
5035CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005036 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005037 LOG_BAD_TU(TU);
5038 return clang_getNullLocation();
5039 }
5040
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005041 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005042 if (!CXXUnit)
5043 return clang_getNullLocation();
5044
5045 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5046 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5047}
5048
5049CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005050 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005051 LOG_BAD_TU(TU);
5052 return clang_getNullRange();
5053 }
5054
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005055 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005056 if (!CXXUnit)
5057 return clang_getNullRange();
5058
5059 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5060 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5061}
5062
5063static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5064 SmallVectorImpl<CXToken> &CXTokens) {
5065 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5066 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005067 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005068 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005069 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005070
5071 // Cannot tokenize across files.
5072 if (BeginLocInfo.first != EndLocInfo.first)
5073 return;
5074
5075 // Create a lexer
5076 bool Invalid = false;
5077 StringRef Buffer
5078 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5079 if (Invalid)
5080 return;
5081
5082 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5083 CXXUnit->getASTContext().getLangOpts(),
5084 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5085 Lex.SetCommentRetentionState(true);
5086
5087 // Lex tokens until we hit the end of the range.
5088 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5089 Token Tok;
5090 bool previousWasAt = false;
5091 do {
5092 // Lex the next token
5093 Lex.LexFromRawLexer(Tok);
5094 if (Tok.is(tok::eof))
5095 break;
5096
5097 // Initialize the CXToken.
5098 CXToken CXTok;
5099
5100 // - Common fields
5101 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5102 CXTok.int_data[2] = Tok.getLength();
5103 CXTok.int_data[3] = 0;
5104
5105 // - Kind-specific fields
5106 if (Tok.isLiteral()) {
5107 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005108 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005109 } else if (Tok.is(tok::raw_identifier)) {
5110 // Lookup the identifier to determine whether we have a keyword.
5111 IdentifierInfo *II
5112 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5113
5114 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5115 CXTok.int_data[0] = CXToken_Keyword;
5116 }
5117 else {
5118 CXTok.int_data[0] = Tok.is(tok::identifier)
5119 ? CXToken_Identifier
5120 : CXToken_Keyword;
5121 }
5122 CXTok.ptr_data = II;
5123 } else if (Tok.is(tok::comment)) {
5124 CXTok.int_data[0] = CXToken_Comment;
5125 CXTok.ptr_data = 0;
5126 } else {
5127 CXTok.int_data[0] = CXToken_Punctuation;
5128 CXTok.ptr_data = 0;
5129 }
5130 CXTokens.push_back(CXTok);
5131 previousWasAt = Tok.is(tok::at);
5132 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5133}
5134
5135void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5136 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005137 LOG_FUNC_SECTION {
5138 *Log << TU << ' ' << Range;
5139 }
5140
Guy Benyei11169dd2012-12-18 14:30:41 +00005141 if (Tokens)
5142 *Tokens = 0;
5143 if (NumTokens)
5144 *NumTokens = 0;
5145
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005146 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005147 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005148 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005149 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005150
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005151 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005152 if (!CXXUnit || !Tokens || !NumTokens)
5153 return;
5154
5155 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5156
5157 SourceRange R = cxloc::translateCXSourceRange(Range);
5158 if (R.isInvalid())
5159 return;
5160
5161 SmallVector<CXToken, 32> CXTokens;
5162 getTokens(CXXUnit, R, CXTokens);
5163
5164 if (CXTokens.empty())
5165 return;
5166
5167 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5168 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5169 *NumTokens = CXTokens.size();
5170}
5171
5172void clang_disposeTokens(CXTranslationUnit TU,
5173 CXToken *Tokens, unsigned NumTokens) {
5174 free(Tokens);
5175}
5176
5177} // end: extern "C"
5178
5179//===----------------------------------------------------------------------===//
5180// Token annotation APIs.
5181//===----------------------------------------------------------------------===//
5182
Guy Benyei11169dd2012-12-18 14:30:41 +00005183static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5184 CXCursor parent,
5185 CXClientData client_data);
5186static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5187 CXClientData client_data);
5188
5189namespace {
5190class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005191 CXToken *Tokens;
5192 CXCursor *Cursors;
5193 unsigned NumTokens;
5194 unsigned TokIdx;
5195 unsigned PreprocessingTokIdx;
5196 CursorVisitor AnnotateVis;
5197 SourceManager &SrcMgr;
5198 bool HasContextSensitiveKeywords;
5199
5200 struct PostChildrenInfo {
5201 CXCursor Cursor;
5202 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005203 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 unsigned BeforeChildrenTokenIdx;
5205 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005206 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005207
5208 CXToken &getTok(unsigned Idx) {
5209 assert(Idx < NumTokens);
5210 return Tokens[Idx];
5211 }
5212 const CXToken &getTok(unsigned Idx) const {
5213 assert(Idx < NumTokens);
5214 return Tokens[Idx];
5215 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 bool MoreTokens() const { return TokIdx < NumTokens; }
5217 unsigned NextToken() const { return TokIdx; }
5218 void AdvanceToken() { ++TokIdx; }
5219 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005220 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005221 }
5222 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005223 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 }
5225 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005226 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005227 }
5228
5229 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005230 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005231 SourceRange);
5232
5233public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005234 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005235 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005236 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005237 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005238 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005239 AnnotateTokensVisitor, this,
5240 /*VisitPreprocessorLast=*/true,
5241 /*VisitIncludedEntities=*/false,
5242 RegionOfInterest,
5243 /*VisitDeclsOnly=*/false,
5244 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005245 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005246 HasContextSensitiveKeywords(false) { }
5247
5248 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5249 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5250 bool postVisitChildren(CXCursor cursor);
5251 void AnnotateTokens();
5252
5253 /// \brief Determine whether the annotator saw any cursors that have
5254 /// context-sensitive keywords.
5255 bool hasContextSensitiveKeywords() const {
5256 return HasContextSensitiveKeywords;
5257 }
5258
5259 ~AnnotateTokensWorker() {
5260 assert(PostChildrenInfos.empty());
5261 }
5262};
5263}
5264
5265void AnnotateTokensWorker::AnnotateTokens() {
5266 // Walk the AST within the region of interest, annotating tokens
5267 // along the way.
5268 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005269}
Guy Benyei11169dd2012-12-18 14:30:41 +00005270
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005271static inline void updateCursorAnnotation(CXCursor &Cursor,
5272 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005273 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005274 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005275 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005276}
5277
5278/// \brief It annotates and advances tokens with a cursor until the comparison
5279//// between the cursor location and the source range is the same as
5280/// \arg compResult.
5281///
5282/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5283/// Pass RangeOverlap to annotate tokens inside a range.
5284void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5285 RangeComparisonResult compResult,
5286 SourceRange range) {
5287 while (MoreTokens()) {
5288 const unsigned I = NextToken();
5289 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005290 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5291 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005292
5293 SourceLocation TokLoc = GetTokenLoc(I);
5294 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005295 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005296 AdvanceToken();
5297 continue;
5298 }
5299 break;
5300 }
5301}
5302
5303/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005304/// \returns true if it advanced beyond all macro tokens, false otherwise.
5305bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005306 CXCursor updateC,
5307 RangeComparisonResult compResult,
5308 SourceRange range) {
5309 assert(MoreTokens());
5310 assert(isFunctionMacroToken(NextToken()) &&
5311 "Should be called only for macro arg tokens");
5312
5313 // This works differently than annotateAndAdvanceTokens; because expanded
5314 // macro arguments can have arbitrary translation-unit source order, we do not
5315 // advance the token index one by one until a token fails the range test.
5316 // We only advance once past all of the macro arg tokens if all of them
5317 // pass the range test. If one of them fails we keep the token index pointing
5318 // at the start of the macro arg tokens so that the failing token will be
5319 // annotated by a subsequent annotation try.
5320
5321 bool atLeastOneCompFail = false;
5322
5323 unsigned I = NextToken();
5324 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5325 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5326 if (TokLoc.isFileID())
5327 continue; // not macro arg token, it's parens or comma.
5328 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5329 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5330 Cursors[I] = updateC;
5331 } else
5332 atLeastOneCompFail = true;
5333 }
5334
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005335 if (atLeastOneCompFail)
5336 return false;
5337
5338 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5339 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005340}
5341
5342enum CXChildVisitResult
5343AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005344 SourceRange cursorRange = getRawCursorExtent(cursor);
5345 if (cursorRange.isInvalid())
5346 return CXChildVisit_Recurse;
5347
5348 if (!HasContextSensitiveKeywords) {
5349 // Objective-C properties can have context-sensitive keywords.
5350 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005351 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005352 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5353 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5354 }
5355 // Objective-C methods can have context-sensitive keywords.
5356 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5357 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005358 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005359 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5360 if (Method->getObjCDeclQualifier())
5361 HasContextSensitiveKeywords = true;
5362 else {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005363 for (ObjCMethodDecl::param_const_iterator P = Method->param_begin(),
5364 PEnd = Method->param_end();
Guy Benyei11169dd2012-12-18 14:30:41 +00005365 P != PEnd; ++P) {
5366 if ((*P)->getObjCDeclQualifier()) {
5367 HasContextSensitiveKeywords = true;
5368 break;
5369 }
5370 }
5371 }
5372 }
5373 }
5374 // C++ methods can have context-sensitive keywords.
5375 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005376 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005377 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5378 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5379 HasContextSensitiveKeywords = true;
5380 }
5381 }
5382 // C++ classes can have context-sensitive keywords.
5383 else if (cursor.kind == CXCursor_StructDecl ||
5384 cursor.kind == CXCursor_ClassDecl ||
5385 cursor.kind == CXCursor_ClassTemplate ||
5386 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005387 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005388 if (D->hasAttr<FinalAttr>())
5389 HasContextSensitiveKeywords = true;
5390 }
5391 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005392
5393 // Don't override a property annotation with its getter/setter method.
5394 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5395 parent.kind == CXCursor_ObjCPropertyDecl)
5396 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005397
5398 if (clang_isPreprocessing(cursor.kind)) {
5399 // Items in the preprocessing record are kept separate from items in
5400 // declarations, so we keep a separate token index.
5401 unsigned SavedTokIdx = TokIdx;
5402 TokIdx = PreprocessingTokIdx;
5403
5404 // Skip tokens up until we catch up to the beginning of the preprocessing
5405 // entry.
5406 while (MoreTokens()) {
5407 const unsigned I = NextToken();
5408 SourceLocation TokLoc = GetTokenLoc(I);
5409 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5410 case RangeBefore:
5411 AdvanceToken();
5412 continue;
5413 case RangeAfter:
5414 case RangeOverlap:
5415 break;
5416 }
5417 break;
5418 }
5419
5420 // Look at all of the tokens within this range.
5421 while (MoreTokens()) {
5422 const unsigned I = NextToken();
5423 SourceLocation TokLoc = GetTokenLoc(I);
5424 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5425 case RangeBefore:
5426 llvm_unreachable("Infeasible");
5427 case RangeAfter:
5428 break;
5429 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005430 // For macro expansions, just note where the beginning of the macro
5431 // expansion occurs.
5432 if (cursor.kind == CXCursor_MacroExpansion) {
5433 if (TokLoc == cursorRange.getBegin())
5434 Cursors[I] = cursor;
5435 AdvanceToken();
5436 break;
5437 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005438 // We may have already annotated macro names inside macro definitions.
5439 if (Cursors[I].kind != CXCursor_MacroExpansion)
5440 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005441 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005442 continue;
5443 }
5444 break;
5445 }
5446
5447 // Save the preprocessing token index; restore the non-preprocessing
5448 // token index.
5449 PreprocessingTokIdx = TokIdx;
5450 TokIdx = SavedTokIdx;
5451 return CXChildVisit_Recurse;
5452 }
5453
5454 if (cursorRange.isInvalid())
5455 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005456
5457 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005458 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005459 const enum CXCursorKind K = clang_getCursorKind(parent);
5460 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005461 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5462 // Attributes are annotated out-of-order, skip tokens until we reach it.
5463 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005464 ? clang_getNullCursor() : parent;
5465
5466 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5467
5468 // Avoid having the cursor of an expression "overwrite" the annotation of the
5469 // variable declaration that it belongs to.
5470 // This can happen for C++ constructor expressions whose range generally
5471 // include the variable declaration, e.g.:
5472 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005473 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005474 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005475 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005476 const unsigned I = NextToken();
5477 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5478 E->getLocStart() == D->getLocation() &&
5479 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005480 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005481 AdvanceToken();
5482 }
5483 }
5484 }
5485
5486 // Before recursing into the children keep some state that we are going
5487 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5488 // extra work after the child nodes are visited.
5489 // Note that we don't call VisitChildren here to avoid traversing statements
5490 // code-recursively which can blow the stack.
5491
5492 PostChildrenInfo Info;
5493 Info.Cursor = cursor;
5494 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005495 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005496 Info.BeforeChildrenTokenIdx = NextToken();
5497 PostChildrenInfos.push_back(Info);
5498
5499 return CXChildVisit_Recurse;
5500}
5501
5502bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5503 if (PostChildrenInfos.empty())
5504 return false;
5505 const PostChildrenInfo &Info = PostChildrenInfos.back();
5506 if (!clang_equalCursors(Info.Cursor, cursor))
5507 return false;
5508
5509 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5510 const unsigned AfterChildren = NextToken();
5511 SourceRange cursorRange = Info.CursorRange;
5512
5513 // Scan the tokens that are at the end of the cursor, but are not captured
5514 // but the child cursors.
5515 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5516
5517 // Scan the tokens that are at the beginning of the cursor, but are not
5518 // capture by the child cursors.
5519 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5520 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5521 break;
5522
5523 Cursors[I] = cursor;
5524 }
5525
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005526 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5527 // encountered the attribute cursor.
5528 if (clang_isAttribute(cursor.kind))
5529 TokIdx = Info.BeforeReachingCursorIdx;
5530
Guy Benyei11169dd2012-12-18 14:30:41 +00005531 PostChildrenInfos.pop_back();
5532 return false;
5533}
5534
5535static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5536 CXCursor parent,
5537 CXClientData client_data) {
5538 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5539}
5540
5541static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5542 CXClientData client_data) {
5543 return static_cast<AnnotateTokensWorker*>(client_data)->
5544 postVisitChildren(cursor);
5545}
5546
5547namespace {
5548
5549/// \brief Uses the macro expansions in the preprocessing record to find
5550/// and mark tokens that are macro arguments. This info is used by the
5551/// AnnotateTokensWorker.
5552class MarkMacroArgTokensVisitor {
5553 SourceManager &SM;
5554 CXToken *Tokens;
5555 unsigned NumTokens;
5556 unsigned CurIdx;
5557
5558public:
5559 MarkMacroArgTokensVisitor(SourceManager &SM,
5560 CXToken *tokens, unsigned numTokens)
5561 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5562
5563 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5564 if (cursor.kind != CXCursor_MacroExpansion)
5565 return CXChildVisit_Continue;
5566
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005567 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005568 if (macroRange.getBegin() == macroRange.getEnd())
5569 return CXChildVisit_Continue; // it's not a function macro.
5570
5571 for (; CurIdx < NumTokens; ++CurIdx) {
5572 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5573 macroRange.getBegin()))
5574 break;
5575 }
5576
5577 if (CurIdx == NumTokens)
5578 return CXChildVisit_Break;
5579
5580 for (; CurIdx < NumTokens; ++CurIdx) {
5581 SourceLocation tokLoc = getTokenLoc(CurIdx);
5582 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5583 break;
5584
5585 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5586 }
5587
5588 if (CurIdx == NumTokens)
5589 return CXChildVisit_Break;
5590
5591 return CXChildVisit_Continue;
5592 }
5593
5594private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005595 CXToken &getTok(unsigned Idx) {
5596 assert(Idx < NumTokens);
5597 return Tokens[Idx];
5598 }
5599 const CXToken &getTok(unsigned Idx) const {
5600 assert(Idx < NumTokens);
5601 return Tokens[Idx];
5602 }
5603
Guy Benyei11169dd2012-12-18 14:30:41 +00005604 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005605 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005606 }
5607
5608 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5609 // The third field is reserved and currently not used. Use it here
5610 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005611 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005612 }
5613};
5614
5615} // end anonymous namespace
5616
5617static CXChildVisitResult
5618MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5619 CXClientData client_data) {
5620 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5621 parent);
5622}
5623
5624namespace {
5625 struct clang_annotateTokens_Data {
5626 CXTranslationUnit TU;
5627 ASTUnit *CXXUnit;
5628 CXToken *Tokens;
5629 unsigned NumTokens;
5630 CXCursor *Cursors;
5631 };
5632}
5633
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005634/// \brief Used by \c annotatePreprocessorTokens.
5635/// \returns true if lexing was finished, false otherwise.
5636static bool lexNext(Lexer &Lex, Token &Tok,
5637 unsigned &NextIdx, unsigned NumTokens) {
5638 if (NextIdx >= NumTokens)
5639 return true;
5640
5641 ++NextIdx;
5642 Lex.LexFromRawLexer(Tok);
5643 if (Tok.is(tok::eof))
5644 return true;
5645
5646 return false;
5647}
5648
Guy Benyei11169dd2012-12-18 14:30:41 +00005649static void annotatePreprocessorTokens(CXTranslationUnit TU,
5650 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005651 CXCursor *Cursors,
5652 CXToken *Tokens,
5653 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005654 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005655
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005656 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005657 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5658 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005659 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005660 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005661 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005662
5663 if (BeginLocInfo.first != EndLocInfo.first)
5664 return;
5665
5666 StringRef Buffer;
5667 bool Invalid = false;
5668 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5669 if (Buffer.empty() || Invalid)
5670 return;
5671
5672 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5673 CXXUnit->getASTContext().getLangOpts(),
5674 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5675 Buffer.end());
5676 Lex.SetCommentRetentionState(true);
5677
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005678 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005679 // Lex tokens in raw mode until we hit the end of the range, to avoid
5680 // entering #includes or expanding macros.
5681 while (true) {
5682 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005683 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5684 break;
5685 unsigned TokIdx = NextIdx-1;
5686 assert(Tok.getLocation() ==
5687 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005688
5689 reprocess:
5690 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005691 // We have found a preprocessing directive. Annotate the tokens
5692 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005693 //
5694 // FIXME: Some simple tests here could identify macro definitions and
5695 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005696
5697 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005698 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5699 break;
5700
5701 MacroInfo *MI = 0;
5702 if (Tok.is(tok::raw_identifier) &&
5703 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5704 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5705 break;
5706
5707 if (Tok.is(tok::raw_identifier)) {
5708 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5709 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5710 SourceLocation MappedTokLoc =
5711 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5712 MI = getMacroInfo(II, MappedTokLoc, TU);
5713 }
5714 }
5715
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005716 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005717 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005718 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5719 finished = true;
5720 break;
5721 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005722 // If we are in a macro definition, check if the token was ever a
5723 // macro name and annotate it if that's the case.
5724 if (MI) {
5725 SourceLocation SaveLoc = Tok.getLocation();
5726 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5727 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5728 Tok.setLocation(SaveLoc);
5729 if (MacroDef)
5730 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5731 Tok.getLocation(), TU);
5732 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005733 } while (!Tok.isAtStartOfLine());
5734
5735 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5736 assert(TokIdx <= LastIdx);
5737 SourceLocation EndLoc =
5738 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5739 CXCursor Cursor =
5740 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5741
5742 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005743 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005744
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005745 if (finished)
5746 break;
5747 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005748 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005749 }
5750}
5751
5752// This gets run a separate thread to avoid stack blowout.
5753static void clang_annotateTokensImpl(void *UserData) {
5754 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5755 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5756 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5757 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5758 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5759
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005760 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005761 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5762 setThreadBackgroundPriority();
5763
5764 // Determine the region of interest, which contains all of the tokens.
5765 SourceRange RegionOfInterest;
5766 RegionOfInterest.setBegin(
5767 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5768 RegionOfInterest.setEnd(
5769 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5770 Tokens[NumTokens-1])));
5771
Guy Benyei11169dd2012-12-18 14:30:41 +00005772 // Relex the tokens within the source range to look for preprocessing
5773 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005774 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005775
5776 // If begin location points inside a macro argument, set it to the expansion
5777 // location so we can have the full context when annotating semantically.
5778 {
5779 SourceManager &SM = CXXUnit->getSourceManager();
5780 SourceLocation Loc =
5781 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5782 if (Loc.isMacroID())
5783 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5784 }
5785
Guy Benyei11169dd2012-12-18 14:30:41 +00005786 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5787 // Search and mark tokens that are macro argument expansions.
5788 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5789 Tokens, NumTokens);
5790 CursorVisitor MacroArgMarker(TU,
5791 MarkMacroArgTokensVisitorDelegate, &Visitor,
5792 /*VisitPreprocessorLast=*/true,
5793 /*VisitIncludedEntities=*/false,
5794 RegionOfInterest);
5795 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5796 }
5797
5798 // Annotate all of the source locations in the region of interest that map to
5799 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005800 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005801
5802 // FIXME: We use a ridiculous stack size here because the data-recursion
5803 // algorithm uses a large stack frame than the non-data recursive version,
5804 // and AnnotationTokensWorker currently transforms the data-recursion
5805 // algorithm back into a traditional recursion by explicitly calling
5806 // VisitChildren(). We will need to remove this explicit recursive call.
5807 W.AnnotateTokens();
5808
5809 // If we ran into any entities that involve context-sensitive keywords,
5810 // take another pass through the tokens to mark them as such.
5811 if (W.hasContextSensitiveKeywords()) {
5812 for (unsigned I = 0; I != NumTokens; ++I) {
5813 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5814 continue;
5815
5816 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5817 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005818 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005819 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5820 if (Property->getPropertyAttributesAsWritten() != 0 &&
5821 llvm::StringSwitch<bool>(II->getName())
5822 .Case("readonly", true)
5823 .Case("assign", true)
5824 .Case("unsafe_unretained", true)
5825 .Case("readwrite", true)
5826 .Case("retain", true)
5827 .Case("copy", true)
5828 .Case("nonatomic", true)
5829 .Case("atomic", true)
5830 .Case("getter", true)
5831 .Case("setter", true)
5832 .Case("strong", true)
5833 .Case("weak", true)
5834 .Default(false))
5835 Tokens[I].int_data[0] = CXToken_Keyword;
5836 }
5837 continue;
5838 }
5839
5840 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5841 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5842 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5843 if (llvm::StringSwitch<bool>(II->getName())
5844 .Case("in", true)
5845 .Case("out", true)
5846 .Case("inout", true)
5847 .Case("oneway", true)
5848 .Case("bycopy", true)
5849 .Case("byref", true)
5850 .Default(false))
5851 Tokens[I].int_data[0] = CXToken_Keyword;
5852 continue;
5853 }
5854
5855 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5856 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5857 Tokens[I].int_data[0] = CXToken_Keyword;
5858 continue;
5859 }
5860 }
5861 }
5862}
5863
5864extern "C" {
5865
5866void clang_annotateTokens(CXTranslationUnit TU,
5867 CXToken *Tokens, unsigned NumTokens,
5868 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005869 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005870 LOG_BAD_TU(TU);
5871 return;
5872 }
5873 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005874 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005875 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005876 }
5877
5878 LOG_FUNC_SECTION {
5879 *Log << TU << ' ';
5880 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5881 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5882 *Log << clang_getRange(bloc, eloc);
5883 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005884
5885 // Any token we don't specifically annotate will have a NULL cursor.
5886 CXCursor C = clang_getNullCursor();
5887 for (unsigned I = 0; I != NumTokens; ++I)
5888 Cursors[I] = C;
5889
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005890 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005891 if (!CXXUnit)
5892 return;
5893
5894 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5895
5896 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5897 llvm::CrashRecoveryContext CRC;
5898 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5899 GetSafetyThreadStackSize() * 2)) {
5900 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5901 }
5902}
5903
5904} // end: extern "C"
5905
5906//===----------------------------------------------------------------------===//
5907// Operations for querying linkage of a cursor.
5908//===----------------------------------------------------------------------===//
5909
5910extern "C" {
5911CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5912 if (!clang_isDeclaration(cursor.kind))
5913 return CXLinkage_Invalid;
5914
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005915 const Decl *D = cxcursor::getCursorDecl(cursor);
5916 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005917 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005918 case NoLinkage:
5919 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005920 case InternalLinkage: return CXLinkage_Internal;
5921 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5922 case ExternalLinkage: return CXLinkage_External;
5923 };
5924
5925 return CXLinkage_Invalid;
5926}
5927} // end: extern "C"
5928
5929//===----------------------------------------------------------------------===//
5930// Operations for querying language of a cursor.
5931//===----------------------------------------------------------------------===//
5932
5933static CXLanguageKind getDeclLanguage(const Decl *D) {
5934 if (!D)
5935 return CXLanguage_C;
5936
5937 switch (D->getKind()) {
5938 default:
5939 break;
5940 case Decl::ImplicitParam:
5941 case Decl::ObjCAtDefsField:
5942 case Decl::ObjCCategory:
5943 case Decl::ObjCCategoryImpl:
5944 case Decl::ObjCCompatibleAlias:
5945 case Decl::ObjCImplementation:
5946 case Decl::ObjCInterface:
5947 case Decl::ObjCIvar:
5948 case Decl::ObjCMethod:
5949 case Decl::ObjCProperty:
5950 case Decl::ObjCPropertyImpl:
5951 case Decl::ObjCProtocol:
5952 return CXLanguage_ObjC;
5953 case Decl::CXXConstructor:
5954 case Decl::CXXConversion:
5955 case Decl::CXXDestructor:
5956 case Decl::CXXMethod:
5957 case Decl::CXXRecord:
5958 case Decl::ClassTemplate:
5959 case Decl::ClassTemplatePartialSpecialization:
5960 case Decl::ClassTemplateSpecialization:
5961 case Decl::Friend:
5962 case Decl::FriendTemplate:
5963 case Decl::FunctionTemplate:
5964 case Decl::LinkageSpec:
5965 case Decl::Namespace:
5966 case Decl::NamespaceAlias:
5967 case Decl::NonTypeTemplateParm:
5968 case Decl::StaticAssert:
5969 case Decl::TemplateTemplateParm:
5970 case Decl::TemplateTypeParm:
5971 case Decl::UnresolvedUsingTypename:
5972 case Decl::UnresolvedUsingValue:
5973 case Decl::Using:
5974 case Decl::UsingDirective:
5975 case Decl::UsingShadow:
5976 return CXLanguage_CPlusPlus;
5977 }
5978
5979 return CXLanguage_C;
5980}
5981
5982extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005983
5984static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5985 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5986 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005987
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005988 switch (D->getAvailability()) {
5989 case AR_Available:
5990 case AR_NotYetIntroduced:
5991 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005992 return getCursorAvailabilityForDecl(
5993 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005994 return CXAvailability_Available;
5995
5996 case AR_Deprecated:
5997 return CXAvailability_Deprecated;
5998
5999 case AR_Unavailable:
6000 return CXAvailability_NotAvailable;
6001 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006002
6003 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006004}
6005
Guy Benyei11169dd2012-12-18 14:30:41 +00006006enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6007 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006008 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6009 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006010
6011 return CXAvailability_Available;
6012}
6013
6014static CXVersion convertVersion(VersionTuple In) {
6015 CXVersion Out = { -1, -1, -1 };
6016 if (In.empty())
6017 return Out;
6018
6019 Out.Major = In.getMajor();
6020
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006021 Optional<unsigned> Minor = In.getMinor();
6022 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006023 Out.Minor = *Minor;
6024 else
6025 return Out;
6026
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006027 Optional<unsigned> Subminor = In.getSubminor();
6028 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006029 Out.Subminor = *Subminor;
6030
6031 return Out;
6032}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006033
6034static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6035 int *always_deprecated,
6036 CXString *deprecated_message,
6037 int *always_unavailable,
6038 CXString *unavailable_message,
6039 CXPlatformAvailability *availability,
6040 int availability_size) {
6041 bool HadAvailAttr = false;
6042 int N = 0;
Aaron Ballman69082962014-03-07 12:50:00 +00006043 for (auto A : D->attrs()) {
6044 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006045 HadAvailAttr = true;
6046 if (always_deprecated)
6047 *always_deprecated = 1;
6048 if (deprecated_message)
6049 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
6050 continue;
6051 }
6052
Aaron Ballman69082962014-03-07 12:50:00 +00006053 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006054 HadAvailAttr = true;
6055 if (always_unavailable)
6056 *always_unavailable = 1;
6057 if (unavailable_message) {
6058 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6059 }
6060 continue;
6061 }
6062
Aaron Ballman69082962014-03-07 12:50:00 +00006063 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006064 HadAvailAttr = true;
6065 if (N < availability_size) {
6066 availability[N].Platform
6067 = cxstring::createDup(Avail->getPlatform()->getName());
6068 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6069 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6070 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6071 availability[N].Unavailable = Avail->getUnavailable();
6072 availability[N].Message = cxstring::createDup(Avail->getMessage());
6073 }
6074 ++N;
6075 }
6076 }
6077
6078 if (!HadAvailAttr)
6079 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6080 return getCursorPlatformAvailabilityForDecl(
6081 cast<Decl>(EnumConst->getDeclContext()),
6082 always_deprecated,
6083 deprecated_message,
6084 always_unavailable,
6085 unavailable_message,
6086 availability,
6087 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006088
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006089 return N;
6090}
6091
Guy Benyei11169dd2012-12-18 14:30:41 +00006092int clang_getCursorPlatformAvailability(CXCursor cursor,
6093 int *always_deprecated,
6094 CXString *deprecated_message,
6095 int *always_unavailable,
6096 CXString *unavailable_message,
6097 CXPlatformAvailability *availability,
6098 int availability_size) {
6099 if (always_deprecated)
6100 *always_deprecated = 0;
6101 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006102 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006103 if (always_unavailable)
6104 *always_unavailable = 0;
6105 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006106 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006107
Guy Benyei11169dd2012-12-18 14:30:41 +00006108 if (!clang_isDeclaration(cursor.kind))
6109 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006110
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006111 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006112 if (!D)
6113 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006114
6115 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6116 deprecated_message,
6117 always_unavailable,
6118 unavailable_message,
6119 availability,
6120 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006121}
6122
6123void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6124 clang_disposeString(availability->Platform);
6125 clang_disposeString(availability->Message);
6126}
6127
6128CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6129 if (clang_isDeclaration(cursor.kind))
6130 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6131
6132 return CXLanguage_Invalid;
6133}
6134
6135 /// \brief If the given cursor is the "templated" declaration
6136 /// descibing a class or function template, return the class or
6137 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006138static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006139 if (!D)
6140 return 0;
6141
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006142 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006143 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6144 return FunTmpl;
6145
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006146 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006147 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6148 return ClassTmpl;
6149
6150 return D;
6151}
6152
6153CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6154 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006155 if (const Decl *D = getCursorDecl(cursor)) {
6156 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006157 if (!DC)
6158 return clang_getNullCursor();
6159
6160 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6161 getCursorTU(cursor));
6162 }
6163 }
6164
6165 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006166 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006167 return MakeCXCursor(D, getCursorTU(cursor));
6168 }
6169
6170 return clang_getNullCursor();
6171}
6172
6173CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6174 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006175 if (const Decl *D = getCursorDecl(cursor)) {
6176 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006177 if (!DC)
6178 return clang_getNullCursor();
6179
6180 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6181 getCursorTU(cursor));
6182 }
6183 }
6184
6185 // FIXME: Note that we can't easily compute the lexical context of a
6186 // statement or expression, so we return nothing.
6187 return clang_getNullCursor();
6188}
6189
6190CXFile clang_getIncludedFile(CXCursor cursor) {
6191 if (cursor.kind != CXCursor_InclusionDirective)
6192 return 0;
6193
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006194 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006195 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006196}
6197
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006198unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6199 if (C.kind != CXCursor_ObjCPropertyDecl)
6200 return CXObjCPropertyAttr_noattr;
6201
6202 unsigned Result = CXObjCPropertyAttr_noattr;
6203 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6204 ObjCPropertyDecl::PropertyAttributeKind Attr =
6205 PD->getPropertyAttributesAsWritten();
6206
6207#define SET_CXOBJCPROP_ATTR(A) \
6208 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6209 Result |= CXObjCPropertyAttr_##A
6210 SET_CXOBJCPROP_ATTR(readonly);
6211 SET_CXOBJCPROP_ATTR(getter);
6212 SET_CXOBJCPROP_ATTR(assign);
6213 SET_CXOBJCPROP_ATTR(readwrite);
6214 SET_CXOBJCPROP_ATTR(retain);
6215 SET_CXOBJCPROP_ATTR(copy);
6216 SET_CXOBJCPROP_ATTR(nonatomic);
6217 SET_CXOBJCPROP_ATTR(setter);
6218 SET_CXOBJCPROP_ATTR(atomic);
6219 SET_CXOBJCPROP_ATTR(weak);
6220 SET_CXOBJCPROP_ATTR(strong);
6221 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6222#undef SET_CXOBJCPROP_ATTR
6223
6224 return Result;
6225}
6226
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006227unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6228 if (!clang_isDeclaration(C.kind))
6229 return CXObjCDeclQualifier_None;
6230
6231 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6232 const Decl *D = getCursorDecl(C);
6233 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6234 QT = MD->getObjCDeclQualifier();
6235 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6236 QT = PD->getObjCDeclQualifier();
6237 if (QT == Decl::OBJC_TQ_None)
6238 return CXObjCDeclQualifier_None;
6239
6240 unsigned Result = CXObjCDeclQualifier_None;
6241 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6242 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6243 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6244 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6245 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6246 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6247
6248 return Result;
6249}
6250
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006251unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6252 if (!clang_isDeclaration(C.kind))
6253 return 0;
6254
6255 const Decl *D = getCursorDecl(C);
6256 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6257 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6258 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6259 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6260
6261 return 0;
6262}
6263
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006264unsigned clang_Cursor_isVariadic(CXCursor C) {
6265 if (!clang_isDeclaration(C.kind))
6266 return 0;
6267
6268 const Decl *D = getCursorDecl(C);
6269 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6270 return FD->isVariadic();
6271 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6272 return MD->isVariadic();
6273
6274 return 0;
6275}
6276
Guy Benyei11169dd2012-12-18 14:30:41 +00006277CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6278 if (!clang_isDeclaration(C.kind))
6279 return clang_getNullRange();
6280
6281 const Decl *D = getCursorDecl(C);
6282 ASTContext &Context = getCursorContext(C);
6283 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6284 if (!RC)
6285 return clang_getNullRange();
6286
6287 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6288}
6289
6290CXString clang_Cursor_getRawCommentText(CXCursor C) {
6291 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006292 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006293
6294 const Decl *D = getCursorDecl(C);
6295 ASTContext &Context = getCursorContext(C);
6296 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6297 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6298 StringRef();
6299
6300 // Don't duplicate the string because RawText points directly into source
6301 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006302 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006303}
6304
6305CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6306 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006307 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006308
6309 const Decl *D = getCursorDecl(C);
6310 const ASTContext &Context = getCursorContext(C);
6311 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6312
6313 if (RC) {
6314 StringRef BriefText = RC->getBriefText(Context);
6315
6316 // Don't duplicate the string because RawComment ensures that this memory
6317 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006318 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006319 }
6320
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006321 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006322}
6323
6324CXComment clang_Cursor_getParsedComment(CXCursor C) {
6325 if (!clang_isDeclaration(C.kind))
6326 return cxcomment::createCXComment(NULL, NULL);
6327
6328 const Decl *D = getCursorDecl(C);
6329 const ASTContext &Context = getCursorContext(C);
6330 const comments::FullComment *FC = Context.getCommentForDecl(D, /*PP=*/ NULL);
6331
6332 return cxcomment::createCXComment(FC, getCursorTU(C));
6333}
6334
6335CXModule clang_Cursor_getModule(CXCursor C) {
6336 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006337 if (const ImportDecl *ImportD =
6338 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006339 return ImportD->getImportedModule();
6340 }
6341
6342 return 0;
6343}
6344
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006345CXFile clang_Module_getASTFile(CXModule CXMod) {
6346 if (!CXMod)
6347 return 0;
6348 Module *Mod = static_cast<Module*>(CXMod);
6349 return const_cast<FileEntry *>(Mod->getASTFile());
6350}
6351
Guy Benyei11169dd2012-12-18 14:30:41 +00006352CXModule clang_Module_getParent(CXModule CXMod) {
6353 if (!CXMod)
6354 return 0;
6355 Module *Mod = static_cast<Module*>(CXMod);
6356 return Mod->Parent;
6357}
6358
6359CXString clang_Module_getName(CXModule CXMod) {
6360 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006361 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006362 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006363 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006364}
6365
6366CXString clang_Module_getFullName(CXModule CXMod) {
6367 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006368 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006369 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006370 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006371}
6372
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006373unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6374 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006375 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006376 LOG_BAD_TU(TU);
6377 return 0;
6378 }
6379 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006380 return 0;
6381 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006382 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6383 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6384 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006385}
6386
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006387CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6388 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006389 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006390 LOG_BAD_TU(TU);
6391 return 0;
6392 }
6393 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006394 return 0;
6395 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006396 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006397
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006398 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6399 if (Index < TopHeaders.size())
6400 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006401
6402 return 0;
6403}
6404
6405} // end: extern "C"
6406
6407//===----------------------------------------------------------------------===//
6408// C++ AST instrospection.
6409//===----------------------------------------------------------------------===//
6410
6411extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006412unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6413 if (!clang_isDeclaration(C.kind))
6414 return 0;
6415
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006416 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006417 const CXXMethodDecl *Method =
6418 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006419 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6420}
6421
Guy Benyei11169dd2012-12-18 14:30:41 +00006422unsigned clang_CXXMethod_isStatic(CXCursor C) {
6423 if (!clang_isDeclaration(C.kind))
6424 return 0;
6425
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006426 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006427 const CXXMethodDecl *Method =
6428 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006429 return (Method && Method->isStatic()) ? 1 : 0;
6430}
6431
6432unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6433 if (!clang_isDeclaration(C.kind))
6434 return 0;
6435
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006436 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006437 const CXXMethodDecl *Method =
6438 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006439 return (Method && Method->isVirtual()) ? 1 : 0;
6440}
6441} // end: extern "C"
6442
6443//===----------------------------------------------------------------------===//
6444// Attribute introspection.
6445//===----------------------------------------------------------------------===//
6446
6447extern "C" {
6448CXType clang_getIBOutletCollectionType(CXCursor C) {
6449 if (C.kind != CXCursor_IBOutletCollectionAttr)
6450 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6451
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006452 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006453 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6454
6455 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6456}
6457} // end: extern "C"
6458
6459//===----------------------------------------------------------------------===//
6460// Inspecting memory usage.
6461//===----------------------------------------------------------------------===//
6462
6463typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6464
6465static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6466 enum CXTUResourceUsageKind k,
6467 unsigned long amount) {
6468 CXTUResourceUsageEntry entry = { k, amount };
6469 entries.push_back(entry);
6470}
6471
6472extern "C" {
6473
6474const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6475 const char *str = "";
6476 switch (kind) {
6477 case CXTUResourceUsage_AST:
6478 str = "ASTContext: expressions, declarations, and types";
6479 break;
6480 case CXTUResourceUsage_Identifiers:
6481 str = "ASTContext: identifiers";
6482 break;
6483 case CXTUResourceUsage_Selectors:
6484 str = "ASTContext: selectors";
6485 break;
6486 case CXTUResourceUsage_GlobalCompletionResults:
6487 str = "Code completion: cached global results";
6488 break;
6489 case CXTUResourceUsage_SourceManagerContentCache:
6490 str = "SourceManager: content cache allocator";
6491 break;
6492 case CXTUResourceUsage_AST_SideTables:
6493 str = "ASTContext: side tables";
6494 break;
6495 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6496 str = "SourceManager: malloc'ed memory buffers";
6497 break;
6498 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6499 str = "SourceManager: mmap'ed memory buffers";
6500 break;
6501 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6502 str = "ExternalASTSource: malloc'ed memory buffers";
6503 break;
6504 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6505 str = "ExternalASTSource: mmap'ed memory buffers";
6506 break;
6507 case CXTUResourceUsage_Preprocessor:
6508 str = "Preprocessor: malloc'ed memory";
6509 break;
6510 case CXTUResourceUsage_PreprocessingRecord:
6511 str = "Preprocessor: PreprocessingRecord";
6512 break;
6513 case CXTUResourceUsage_SourceManager_DataStructures:
6514 str = "SourceManager: data structures and tables";
6515 break;
6516 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6517 str = "Preprocessor: header search tables";
6518 break;
6519 }
6520 return str;
6521}
6522
6523CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006524 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006525 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006526 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6527 return usage;
6528 }
6529
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006530 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006531 OwningPtr<MemUsageEntries> entries(new MemUsageEntries());
6532 ASTContext &astContext = astUnit->getASTContext();
6533
6534 // How much memory is used by AST nodes and types?
6535 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6536 (unsigned long) astContext.getASTAllocatedMemory());
6537
6538 // How much memory is used by identifiers?
6539 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6540 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6541
6542 // How much memory is used for selectors?
6543 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6544 (unsigned long) astContext.Selectors.getTotalMemory());
6545
6546 // How much memory is used by ASTContext's side tables?
6547 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6548 (unsigned long) astContext.getSideTableAllocatedMemory());
6549
6550 // How much memory is used for caching global code completion results?
6551 unsigned long completionBytes = 0;
6552 if (GlobalCodeCompletionAllocator *completionAllocator =
6553 astUnit->getCachedCompletionAllocator().getPtr()) {
6554 completionBytes = completionAllocator->getTotalMemory();
6555 }
6556 createCXTUResourceUsageEntry(*entries,
6557 CXTUResourceUsage_GlobalCompletionResults,
6558 completionBytes);
6559
6560 // How much memory is being used by SourceManager's content cache?
6561 createCXTUResourceUsageEntry(*entries,
6562 CXTUResourceUsage_SourceManagerContentCache,
6563 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6564
6565 // How much memory is being used by the MemoryBuffer's in SourceManager?
6566 const SourceManager::MemoryBufferSizes &srcBufs =
6567 astUnit->getSourceManager().getMemoryBufferSizes();
6568
6569 createCXTUResourceUsageEntry(*entries,
6570 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6571 (unsigned long) srcBufs.malloc_bytes);
6572 createCXTUResourceUsageEntry(*entries,
6573 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6574 (unsigned long) srcBufs.mmap_bytes);
6575 createCXTUResourceUsageEntry(*entries,
6576 CXTUResourceUsage_SourceManager_DataStructures,
6577 (unsigned long) astContext.getSourceManager()
6578 .getDataStructureSizes());
6579
6580 // How much memory is being used by the ExternalASTSource?
6581 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6582 const ExternalASTSource::MemoryBufferSizes &sizes =
6583 esrc->getMemoryBufferSizes();
6584
6585 createCXTUResourceUsageEntry(*entries,
6586 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6587 (unsigned long) sizes.malloc_bytes);
6588 createCXTUResourceUsageEntry(*entries,
6589 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6590 (unsigned long) sizes.mmap_bytes);
6591 }
6592
6593 // How much memory is being used by the Preprocessor?
6594 Preprocessor &pp = astUnit->getPreprocessor();
6595 createCXTUResourceUsageEntry(*entries,
6596 CXTUResourceUsage_Preprocessor,
6597 pp.getTotalMemory());
6598
6599 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6600 createCXTUResourceUsageEntry(*entries,
6601 CXTUResourceUsage_PreprocessingRecord,
6602 pRec->getTotalMemory());
6603 }
6604
6605 createCXTUResourceUsageEntry(*entries,
6606 CXTUResourceUsage_Preprocessor_HeaderSearch,
6607 pp.getHeaderSearchInfo().getTotalMemory());
6608
6609 CXTUResourceUsage usage = { (void*) entries.get(),
6610 (unsigned) entries->size(),
6611 entries->size() ? &(*entries)[0] : 0 };
6612 entries.take();
6613 return usage;
6614}
6615
6616void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6617 if (usage.data)
6618 delete (MemUsageEntries*) usage.data;
6619}
6620
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006621CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6622 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006623 skipped->count = 0;
6624 skipped->ranges = 0;
6625
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006626 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006627 LOG_BAD_TU(TU);
6628 return skipped;
6629 }
6630
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006631 if (!file)
6632 return skipped;
6633
6634 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6635 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6636 if (!ppRec)
6637 return skipped;
6638
6639 ASTContext &Ctx = astUnit->getASTContext();
6640 SourceManager &sm = Ctx.getSourceManager();
6641 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6642 FileID wantedFileID = sm.translateFile(fileEntry);
6643
6644 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6645 std::vector<SourceRange> wantedRanges;
6646 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6647 i != ei; ++i) {
6648 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6649 wantedRanges.push_back(*i);
6650 }
6651
6652 skipped->count = wantedRanges.size();
6653 skipped->ranges = new CXSourceRange[skipped->count];
6654 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6655 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6656
6657 return skipped;
6658}
6659
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006660void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6661 if (ranges) {
6662 delete[] ranges->ranges;
6663 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006664 }
6665}
6666
Guy Benyei11169dd2012-12-18 14:30:41 +00006667} // end extern "C"
6668
6669void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6670 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6671 for (unsigned I = 0; I != Usage.numEntries; ++I)
6672 fprintf(stderr, " %s: %lu\n",
6673 clang_getTUResourceUsageName(Usage.entries[I].kind),
6674 Usage.entries[I].amount);
6675
6676 clang_disposeCXTUResourceUsage(Usage);
6677}
6678
6679//===----------------------------------------------------------------------===//
6680// Misc. utility functions.
6681//===----------------------------------------------------------------------===//
6682
6683/// Default to using an 8 MB stack size on "safety" threads.
6684static unsigned SafetyStackThreadSize = 8 << 20;
6685
6686namespace clang {
6687
6688bool RunSafely(llvm::CrashRecoveryContext &CRC,
6689 void (*Fn)(void*), void *UserData,
6690 unsigned Size) {
6691 if (!Size)
6692 Size = GetSafetyThreadStackSize();
6693 if (Size)
6694 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6695 return CRC.RunSafely(Fn, UserData);
6696}
6697
6698unsigned GetSafetyThreadStackSize() {
6699 return SafetyStackThreadSize;
6700}
6701
6702void SetSafetyThreadStackSize(unsigned Value) {
6703 SafetyStackThreadSize = Value;
6704}
6705
6706}
6707
6708void clang::setThreadBackgroundPriority() {
6709 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6710 return;
6711
6712 // FIXME: Move to llvm/Support and make it cross-platform.
6713#ifdef __APPLE__
6714 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6715#endif
6716}
6717
6718void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6719 if (!Unit)
6720 return;
6721
6722 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6723 DEnd = Unit->stored_diag_end();
6724 D != DEnd; ++D) {
6725 CXStoredDiagnostic Diag(*D, Unit->getASTContext().getLangOpts());
6726 CXString Msg = clang_formatDiagnostic(&Diag,
6727 clang_defaultDiagnosticDisplayOptions());
6728 fprintf(stderr, "%s\n", clang_getCString(Msg));
6729 clang_disposeString(Msg);
6730 }
6731#ifdef LLVM_ON_WIN32
6732 // On Windows, force a flush, since there may be multiple copies of
6733 // stderr and stdout in the file system, all with different buffers
6734 // but writing to the same device.
6735 fflush(stderr);
6736#endif
6737}
6738
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006739MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6740 SourceLocation MacroDefLoc,
6741 CXTranslationUnit TU){
6742 if (MacroDefLoc.isInvalid() || !TU)
6743 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006744 if (!II.hadMacroDefinition())
6745 return 0;
6746
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006747 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006748 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006749 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006750 if (MD) {
6751 for (MacroDirective::DefInfo
6752 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6753 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6754 return Def.getMacroInfo();
6755 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006756 }
6757
6758 return 0;
6759}
6760
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006761const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6762 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006763 if (!MacroDef || !TU)
6764 return 0;
6765 const IdentifierInfo *II = MacroDef->getName();
6766 if (!II)
6767 return 0;
6768
6769 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6770}
6771
6772MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6773 const Token &Tok,
6774 CXTranslationUnit TU) {
6775 if (!MI || !TU)
6776 return 0;
6777 if (Tok.isNot(tok::raw_identifier))
6778 return 0;
6779
6780 if (MI->getNumTokens() == 0)
6781 return 0;
6782 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6783 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006784 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006785
6786 // Check that the token is inside the definition and not its argument list.
6787 SourceManager &SM = Unit->getSourceManager();
6788 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6789 return 0;
6790 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6791 return 0;
6792
6793 Preprocessor &PP = Unit->getPreprocessor();
6794 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6795 if (!PPRec)
6796 return 0;
6797
6798 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6799 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6800 if (!II.hadMacroDefinition())
6801 return 0;
6802
6803 // Check that the identifier is not one of the macro arguments.
6804 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6805 return 0;
6806
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006807 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6808 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006809 return 0;
6810
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006811 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006812}
6813
6814MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6815 SourceLocation Loc,
6816 CXTranslationUnit TU) {
6817 if (Loc.isInvalid() || !MI || !TU)
6818 return 0;
6819
6820 if (MI->getNumTokens() == 0)
6821 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006822 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006823 Preprocessor &PP = Unit->getPreprocessor();
6824 if (!PP.getPreprocessingRecord())
6825 return 0;
6826 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6827 Token Tok;
6828 if (PP.getRawToken(Loc, Tok))
6829 return 0;
6830
6831 return checkForMacroInMacroDefinition(MI, Tok, TU);
6832}
6833
Guy Benyei11169dd2012-12-18 14:30:41 +00006834extern "C" {
6835
6836CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006837 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006838}
6839
6840} // end: extern "C"
6841
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006842Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6843 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006844 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006845 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006846 if (Unit->isMainFileAST())
6847 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006848 return *this;
6849 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006850 } else {
6851 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006852 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006853 return *this;
6854}
6855
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006856Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6857 *this << FE->getName();
6858 return *this;
6859}
6860
6861Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6862 CXString cursorName = clang_getCursorDisplayName(cursor);
6863 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6864 clang_disposeString(cursorName);
6865 return *this;
6866}
6867
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006868Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6869 CXFile File;
6870 unsigned Line, Column;
6871 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6872 CXString FileName = clang_getFileName(File);
6873 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6874 clang_disposeString(FileName);
6875 return *this;
6876}
6877
6878Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6879 CXSourceLocation BLoc = clang_getRangeStart(range);
6880 CXSourceLocation ELoc = clang_getRangeEnd(range);
6881
6882 CXFile BFile;
6883 unsigned BLine, BColumn;
6884 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6885
6886 CXFile EFile;
6887 unsigned ELine, EColumn;
6888 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6889
6890 CXString BFileName = clang_getFileName(BFile);
6891 if (BFile == EFile) {
6892 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6893 BLine, BColumn, ELine, EColumn);
6894 } else {
6895 CXString EFileName = clang_getFileName(EFile);
6896 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6897 BLine, BColumn)
6898 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6899 ELine, EColumn);
6900 clang_disposeString(EFileName);
6901 }
6902 clang_disposeString(BFileName);
6903 return *this;
6904}
6905
6906Logger &cxindex::Logger::operator<<(CXString Str) {
6907 *this << clang_getCString(Str);
6908 return *this;
6909}
6910
6911Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6912 LogOS << Fmt;
6913 return *this;
6914}
6915
6916cxindex::Logger::~Logger() {
6917 LogOS.flush();
6918
6919 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6920
6921 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6922
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006923 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006924 OS << "[libclang:" << Name << ':';
6925
6926 // FIXME: Portability.
6927#if HAVE_PTHREAD_H && __APPLE__
6928 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6929 OS << tid << ':';
6930#endif
6931
6932 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6933 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6934 OS << Msg.str() << '\n';
6935
6936 if (Trace) {
6937 llvm::sys::PrintStackTrace(stderr);
6938 OS << "--------------------------------------------------\n";
6939 }
6940}