blob: 5191dbfa9b7d6cb49c6dcaeea800b6753a613853 [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 "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000025#include "clang/AST/StmtVisitor.h"
26#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000027#include "clang/Basic/DiagnosticCategories.h"
28#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000029#include "clang/Basic/Version.h"
30#include "clang/Frontend/ASTUnit.h"
31#include "clang/Frontend/CompilerInstance.h"
32#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000033#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000034#include "clang/Lex/HeaderSearch.h"
35#include "clang/Lex/Lexer.h"
36#include "clang/Lex/PreprocessingRecord.h"
37#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000038#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000039#include "llvm/ADT/Optional.h"
40#include "llvm/ADT/STLExtras.h"
41#include "llvm/ADT/StringSwitch.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000042#include "llvm/Config/config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000043#include "llvm/Support/Compiler.h"
44#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000045#include "llvm/Support/Format.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000046#include "llvm/Support/MemoryBuffer.h"
47#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000048#include "llvm/Support/Program.h"
49#include "llvm/Support/SaveAndRestore.h"
50#include "llvm/Support/Signals.h"
51#include "llvm/Support/Threading.h"
52#include "llvm/Support/Timer.h"
53#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000054
55#if HAVE_PTHREAD_H
56#include <pthread.h>
57#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000058
59using namespace clang;
60using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000061using namespace clang::cxtu;
62using namespace clang::cxindex;
63
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000064CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
65 if (!AU)
Guy Benyei11169dd2012-12-18 14:30:41 +000066 return 0;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000067 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000068 CXTranslationUnit D = new CXTranslationUnitImpl();
69 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000070 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000071 D->StringPool = new cxstring::CXStringPool();
Guy Benyei11169dd2012-12-18 14:30:41 +000072 D->Diagnostics = 0;
73 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Dmitri Gribenko9e605112013-11-13 22:16:51 +000074 D->CommentToXML = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +000075 return D;
76}
77
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000078bool cxtu::isASTReadError(ASTUnit *AU) {
79 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
80 DEnd = AU->stored_diag_end();
81 D != DEnd; ++D) {
82 if (D->getLevel() >= DiagnosticsEngine::Error &&
83 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
84 diag::DiagCat_AST_Deserialization_Issue)
85 return true;
86 }
87 return false;
88}
89
Guy Benyei11169dd2012-12-18 14:30:41 +000090cxtu::CXTUOwner::~CXTUOwner() {
91 if (TU)
92 clang_disposeTranslationUnit(TU);
93}
94
95/// \brief Compare two source ranges to determine their relative position in
96/// the translation unit.
97static RangeComparisonResult RangeCompare(SourceManager &SM,
98 SourceRange R1,
99 SourceRange R2) {
100 assert(R1.isValid() && "First range is invalid?");
101 assert(R2.isValid() && "Second range is invalid?");
102 if (R1.getEnd() != R2.getBegin() &&
103 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
104 return RangeBefore;
105 if (R2.getEnd() != R1.getBegin() &&
106 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
107 return RangeAfter;
108 return RangeOverlap;
109}
110
111/// \brief Determine if a source location falls within, before, or after a
112/// a given source range.
113static RangeComparisonResult LocationCompare(SourceManager &SM,
114 SourceLocation L, SourceRange R) {
115 assert(R.isValid() && "First range is invalid?");
116 assert(L.isValid() && "Second range is invalid?");
117 if (L == R.getBegin() || L == R.getEnd())
118 return RangeOverlap;
119 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
120 return RangeBefore;
121 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
122 return RangeAfter;
123 return RangeOverlap;
124}
125
126/// \brief Translate a Clang source range into a CIndex source range.
127///
128/// Clang internally represents ranges where the end location points to the
129/// start of the token at the end. However, for external clients it is more
130/// useful to have a CXSourceRange be a proper half-open interval. This routine
131/// does the appropriate translation.
132CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
133 const LangOptions &LangOpts,
134 const CharSourceRange &R) {
135 // We want the last character in this location, so we will adjust the
136 // location accordingly.
137 SourceLocation EndLoc = R.getEnd();
138 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
139 EndLoc = SM.getExpansionRange(EndLoc).second;
140 if (R.isTokenRange() && !EndLoc.isInvalid()) {
141 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
142 SM, LangOpts);
143 EndLoc = EndLoc.getLocWithOffset(Length);
144 }
145
Bill Wendlingeade3622013-01-23 08:25:41 +0000146 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000147 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000148 R.getBegin().getRawEncoding(),
149 EndLoc.getRawEncoding()
150 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000151 return Result;
152}
153
154//===----------------------------------------------------------------------===//
155// Cursor visitor.
156//===----------------------------------------------------------------------===//
157
158static SourceRange getRawCursorExtent(CXCursor C);
159static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
160
161
162RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
163 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
164}
165
166/// \brief Visit the given cursor and, if requested by the visitor,
167/// its children.
168///
169/// \param Cursor the cursor to visit.
170///
171/// \param CheckedRegionOfInterest if true, then the caller already checked
172/// that this cursor is within the region of interest.
173///
174/// \returns true if the visitation should be aborted, false if it
175/// should continue.
176bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
177 if (clang_isInvalid(Cursor.kind))
178 return false;
179
180 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000181 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000182 if (!D) {
183 assert(0 && "Invalid declaration cursor");
184 return true; // abort.
185 }
186
187 // Ignore implicit declarations, unless it's an objc method because
188 // currently we should report implicit methods for properties when indexing.
189 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
190 return false;
191 }
192
193 // If we have a range of interest, and this cursor doesn't intersect with it,
194 // we're done.
195 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
196 SourceRange Range = getRawCursorExtent(Cursor);
197 if (Range.isInvalid() || CompareRegionOfInterest(Range))
198 return false;
199 }
200
201 switch (Visitor(Cursor, Parent, ClientData)) {
202 case CXChildVisit_Break:
203 return true;
204
205 case CXChildVisit_Continue:
206 return false;
207
208 case CXChildVisit_Recurse: {
209 bool ret = VisitChildren(Cursor);
210 if (PostChildrenVisitor)
211 if (PostChildrenVisitor(Cursor, ClientData))
212 return true;
213 return ret;
214 }
215 }
216
217 llvm_unreachable("Invalid CXChildVisitResult!");
218}
219
220static bool visitPreprocessedEntitiesInRange(SourceRange R,
221 PreprocessingRecord &PPRec,
222 CursorVisitor &Visitor) {
223 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
224 FileID FID;
225
226 if (!Visitor.shouldVisitIncludedEntities()) {
227 // If the begin/end of the range lie in the same FileID, do the optimization
228 // where we skip preprocessed entities that do not come from the same FileID.
229 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
230 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
231 FID = FileID();
232 }
233
234 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
235 Entities = PPRec.getPreprocessedEntitiesInRange(R);
236 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
237 PPRec, FID);
238}
239
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000240bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000241 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000242 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000243
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000244 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000245 SourceManager &SM = Unit->getSourceManager();
246
247 std::pair<FileID, unsigned>
248 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
249 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
250
251 if (End.first != Begin.first) {
252 // If the end does not reside in the same file, try to recover by
253 // picking the end of the file of begin location.
254 End.first = Begin.first;
255 End.second = SM.getFileIDSize(Begin.first);
256 }
257
258 assert(Begin.first == End.first);
259 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000260 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000261
262 FileID File = Begin.first;
263 unsigned Offset = Begin.second;
264 unsigned Length = End.second - Begin.second;
265
266 if (!VisitDeclsOnly && !VisitPreprocessorLast)
267 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000268 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000269
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000270 if (visitDeclsFromFileRegion(File, Offset, Length))
271 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000272
273 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000274 return visitPreprocessedEntitiesInRegion();
275
276 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000277}
278
279static bool isInLexicalContext(Decl *D, DeclContext *DC) {
280 if (!DC)
281 return false;
282
283 for (DeclContext *DeclDC = D->getLexicalDeclContext();
284 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
285 if (DeclDC == DC)
286 return true;
287 }
288 return false;
289}
290
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000291bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000292 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000293 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000294 SourceManager &SM = Unit->getSourceManager();
295 SourceRange Range = RegionOfInterest;
296
297 SmallVector<Decl *, 16> Decls;
298 Unit->findFileRegionDecls(File, Offset, Length, Decls);
299
300 // If we didn't find any file level decls for the file, try looking at the
301 // file that it was included from.
302 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
303 bool Invalid = false;
304 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
305 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000306 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000307
308 SourceLocation Outer;
309 if (SLEntry.isFile())
310 Outer = SLEntry.getFile().getIncludeLoc();
311 else
312 Outer = SLEntry.getExpansion().getExpansionLocStart();
313 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000314 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000315
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000316 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000317 Length = 0;
318 Unit->findFileRegionDecls(File, Offset, Length, Decls);
319 }
320
321 assert(!Decls.empty());
322
323 bool VisitedAtLeastOnce = false;
324 DeclContext *CurDC = 0;
Craig Topper2341c0d2013-07-04 03:08:24 +0000325 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
326 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000327 Decl *D = *DIt;
328 if (D->getSourceRange().isInvalid())
329 continue;
330
331 if (isInLexicalContext(D, CurDC))
332 continue;
333
334 CurDC = dyn_cast<DeclContext>(D);
335
336 if (TagDecl *TD = dyn_cast<TagDecl>(D))
337 if (!TD->isFreeStanding())
338 continue;
339
340 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
341 if (CompRes == RangeBefore)
342 continue;
343 if (CompRes == RangeAfter)
344 break;
345
346 assert(CompRes == RangeOverlap);
347 VisitedAtLeastOnce = true;
348
349 if (isa<ObjCContainerDecl>(D)) {
350 FileDI_current = &DIt;
351 FileDE_current = DE;
352 } else {
353 FileDI_current = 0;
354 }
355
356 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000357 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000358 }
359
360 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000361 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000362
363 // No Decls overlapped with the range. Move up the lexical context until there
364 // is a context that contains the range or we reach the translation unit
365 // level.
366 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
367 : (*(DIt-1))->getLexicalDeclContext();
368
369 while (DC && !DC->isTranslationUnit()) {
370 Decl *D = cast<Decl>(DC);
371 SourceRange CurDeclRange = D->getSourceRange();
372 if (CurDeclRange.isInvalid())
373 break;
374
375 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000376 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
377 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000378 }
379
380 DC = D->getLexicalDeclContext();
381 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000382
383 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000384}
385
386bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
387 if (!AU->getPreprocessor().getPreprocessingRecord())
388 return false;
389
390 PreprocessingRecord &PPRec
391 = *AU->getPreprocessor().getPreprocessingRecord();
392 SourceManager &SM = AU->getSourceManager();
393
394 if (RegionOfInterest.isValid()) {
395 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
396 SourceLocation B = MappedRange.getBegin();
397 SourceLocation E = MappedRange.getEnd();
398
399 if (AU->isInPreambleFileID(B)) {
400 if (SM.isLoadedSourceLocation(E))
401 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
402 PPRec, *this);
403
404 // Beginning of range lies in the preamble but it also extends beyond
405 // it into the main file. Split the range into 2 parts, one covering
406 // the preamble and another covering the main file. This allows subsequent
407 // calls to visitPreprocessedEntitiesInRange to accept a source range that
408 // lies in the same FileID, allowing it to skip preprocessed entities that
409 // do not come from the same FileID.
410 bool breaked =
411 visitPreprocessedEntitiesInRange(
412 SourceRange(B, AU->getEndOfPreambleFileID()),
413 PPRec, *this);
414 if (breaked) return true;
415 return visitPreprocessedEntitiesInRange(
416 SourceRange(AU->getStartOfMainFileID(), E),
417 PPRec, *this);
418 }
419
420 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
421 }
422
423 bool OnlyLocalDecls
424 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
425
426 if (OnlyLocalDecls)
427 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
428 PPRec);
429
430 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
431}
432
433template<typename InputIterator>
434bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
435 InputIterator Last,
436 PreprocessingRecord &PPRec,
437 FileID FID) {
438 for (; First != Last; ++First) {
439 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
440 continue;
441
442 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000443 if (!PPE)
444 continue;
445
Guy Benyei11169dd2012-12-18 14:30:41 +0000446 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
447 if (Visit(MakeMacroExpansionCursor(ME, TU)))
448 return true;
449
450 continue;
451 }
452
453 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
454 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
455 return true;
456
457 continue;
458 }
459
460 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
461 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
462 return true;
463
464 continue;
465 }
466 }
467
468 return false;
469}
470
471/// \brief Visit the children of the given cursor.
472///
473/// \returns true if the visitation should be aborted, false if it
474/// should continue.
475bool CursorVisitor::VisitChildren(CXCursor Cursor) {
476 if (clang_isReference(Cursor.kind) &&
477 Cursor.kind != CXCursor_CXXBaseSpecifier) {
478 // By definition, references have no children.
479 return false;
480 }
481
482 // Set the Parent field to Cursor, then back to its old value once we're
483 // done.
484 SetParentRAII SetParent(Parent, StmtParent, Cursor);
485
486 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000487 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000488 if (!D)
489 return false;
490
491 return VisitAttributes(D) || Visit(D);
492 }
493
494 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000495 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000496 return Visit(S);
497
498 return false;
499 }
500
501 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000502 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000503 return Visit(E);
504
505 return false;
506 }
507
508 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000509 CXTranslationUnit TU = getCursorTU(Cursor);
510 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000511
512 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
513 for (unsigned I = 0; I != 2; ++I) {
514 if (VisitOrder[I]) {
515 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
516 RegionOfInterest.isInvalid()) {
517 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
518 TLEnd = CXXUnit->top_level_end();
519 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000520 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000521 return true;
522 }
523 } else if (VisitDeclContext(
524 CXXUnit->getASTContext().getTranslationUnitDecl()))
525 return true;
526 continue;
527 }
528
529 // Walk the preprocessing record.
530 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
531 visitPreprocessedEntitiesInRegion();
532 }
533
534 return false;
535 }
536
537 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000538 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000539 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
540 return Visit(BaseTSInfo->getTypeLoc());
541 }
542 }
543 }
544
545 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000546 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000547 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000548 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000549 return Visit(cxcursor::MakeCursorObjCClassRef(
550 ObjT->getInterface(),
551 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000552 }
553
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000554 // If pointing inside a macro definition, check if the token is an identifier
555 // that was ever defined as a macro. In such a case, create a "pseudo" macro
556 // expansion cursor for that token.
557 SourceLocation BeginLoc = RegionOfInterest.getBegin();
558 if (Cursor.kind == CXCursor_MacroDefinition &&
559 BeginLoc == RegionOfInterest.getEnd()) {
560 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000561 const MacroInfo *MI =
562 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000563 if (MacroDefinition *MacroDef =
564 checkForMacroInMacroDefinition(MI, Loc, TU))
565 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
566 }
567
Guy Benyei11169dd2012-12-18 14:30:41 +0000568 // Nothing to visit at the moment.
569 return false;
570}
571
572bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
573 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
574 if (Visit(TSInfo->getTypeLoc()))
575 return true;
576
577 if (Stmt *Body = B->getBody())
578 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
579
580 return false;
581}
582
Ted Kremenek03325582013-02-21 01:29:01 +0000583Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000584 if (RegionOfInterest.isValid()) {
585 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
586 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000587 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000588
589 switch (CompareRegionOfInterest(Range)) {
590 case RangeBefore:
591 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000592 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000593
594 case RangeAfter:
595 // This declaration comes after the region of interest; we're done.
596 return false;
597
598 case RangeOverlap:
599 // This declaration overlaps the region of interest; visit it.
600 break;
601 }
602 }
603 return true;
604}
605
606bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
607 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
608
609 // FIXME: Eventually remove. This part of a hack to support proper
610 // iteration over all Decls contained lexically within an ObjC container.
611 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
612 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
613
614 for ( ; I != E; ++I) {
615 Decl *D = *I;
616 if (D->getLexicalDeclContext() != DC)
617 continue;
618 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
619
620 // Ignore synthesized ivars here, otherwise if we have something like:
621 // @synthesize prop = _prop;
622 // and '_prop' is not declared, we will encounter a '_prop' ivar before
623 // encountering the 'prop' synthesize declaration and we will think that
624 // we passed the region-of-interest.
625 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
626 if (ivarD->getSynthesize())
627 continue;
628 }
629
630 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
631 // declarations is a mismatch with the compiler semantics.
632 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
633 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
634 if (!ID->isThisDeclarationADefinition())
635 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
636
637 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
638 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
639 if (!PD->isThisDeclarationADefinition())
640 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
641 }
642
Ted Kremenek03325582013-02-21 01:29:01 +0000643 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000644 if (!V.hasValue())
645 continue;
646 if (!V.getValue())
647 return false;
648 if (Visit(Cursor, true))
649 return true;
650 }
651 return false;
652}
653
654bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
655 llvm_unreachable("Translation units are visited directly by Visit()");
656}
657
658bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
659 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
660 return Visit(TSInfo->getTypeLoc());
661
662 return false;
663}
664
665bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
666 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
667 return Visit(TSInfo->getTypeLoc());
668
669 return false;
670}
671
672bool CursorVisitor::VisitTagDecl(TagDecl *D) {
673 return VisitDeclContext(D);
674}
675
676bool CursorVisitor::VisitClassTemplateSpecializationDecl(
677 ClassTemplateSpecializationDecl *D) {
678 bool ShouldVisitBody = false;
679 switch (D->getSpecializationKind()) {
680 case TSK_Undeclared:
681 case TSK_ImplicitInstantiation:
682 // Nothing to visit
683 return false;
684
685 case TSK_ExplicitInstantiationDeclaration:
686 case TSK_ExplicitInstantiationDefinition:
687 break;
688
689 case TSK_ExplicitSpecialization:
690 ShouldVisitBody = true;
691 break;
692 }
693
694 // Visit the template arguments used in the specialization.
695 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
696 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000697 if (TemplateSpecializationTypeLoc TSTLoc =
698 TL.getAs<TemplateSpecializationTypeLoc>()) {
699 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
700 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000701 return true;
702 }
703 }
704
705 if (ShouldVisitBody && VisitCXXRecordDecl(D))
706 return true;
707
708 return false;
709}
710
711bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
712 ClassTemplatePartialSpecializationDecl *D) {
713 // FIXME: Visit the "outer" template parameter lists on the TagDecl
714 // before visiting these template parameters.
715 if (VisitTemplateParameters(D->getTemplateParameters()))
716 return true;
717
718 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000719 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
720 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
721 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000722 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
723 return true;
724
725 return VisitCXXRecordDecl(D);
726}
727
728bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
729 // Visit the default argument.
730 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
731 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
732 if (Visit(DefArg->getTypeLoc()))
733 return true;
734
735 return false;
736}
737
738bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
739 if (Expr *Init = D->getInitExpr())
740 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
741 return false;
742}
743
744bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000745 unsigned NumParamList = DD->getNumTemplateParameterLists();
746 for (unsigned i = 0; i < NumParamList; i++) {
747 TemplateParameterList* Params = DD->getTemplateParameterList(i);
748 if (VisitTemplateParameters(Params))
749 return true;
750 }
751
Guy Benyei11169dd2012-12-18 14:30:41 +0000752 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
753 if (Visit(TSInfo->getTypeLoc()))
754 return true;
755
756 // Visit the nested-name-specifier, if present.
757 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
758 if (VisitNestedNameSpecifierLoc(QualifierLoc))
759 return true;
760
761 return false;
762}
763
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000764/// \brief Compare two base or member initializers based on their source order.
765static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
766 CXXCtorInitializer *const *Y) {
767 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
768}
769
Guy Benyei11169dd2012-12-18 14:30:41 +0000770bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000771 unsigned NumParamList = ND->getNumTemplateParameterLists();
772 for (unsigned i = 0; i < NumParamList; i++) {
773 TemplateParameterList* Params = ND->getTemplateParameterList(i);
774 if (VisitTemplateParameters(Params))
775 return true;
776 }
777
Guy Benyei11169dd2012-12-18 14:30:41 +0000778 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
779 // Visit the function declaration's syntactic components in the order
780 // written. This requires a bit of work.
781 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000782 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000783
784 // If we have a function declared directly (without the use of a typedef),
785 // visit just the return type. Otherwise, just visit the function's type
786 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000787 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000788 (!FTL && Visit(TL)))
789 return true;
790
791 // Visit the nested-name-specifier, if present.
792 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
793 if (VisitNestedNameSpecifierLoc(QualifierLoc))
794 return true;
795
796 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000797 if (!isa<CXXDestructorDecl>(ND))
798 if (VisitDeclarationNameInfo(ND->getNameInfo()))
799 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000800
801 // FIXME: Visit explicitly-specified template arguments!
802
803 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000804 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000805 return true;
806
Bill Wendling44426052012-12-20 19:22:21 +0000807 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000808 }
809
810 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
811 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
812 // Find the initializers that were written in the source.
813 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000814 for (auto *I : Constructor->inits()) {
815 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000816 continue;
817
Aaron Ballman0ad78302014-03-13 17:34:31 +0000818 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000819 }
820
821 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000822 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
823 &CompareCXXCtorInitializers);
824
Guy Benyei11169dd2012-12-18 14:30:41 +0000825 // Visit the initializers in source order
826 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
827 CXXCtorInitializer *Init = WrittenInits[I];
828 if (Init->isAnyMemberInitializer()) {
829 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
830 Init->getMemberLocation(), TU)))
831 return true;
832 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
833 if (Visit(TInfo->getTypeLoc()))
834 return true;
835 }
836
837 // Visit the initializer value.
838 if (Expr *Initializer = Init->getInit())
839 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
840 return true;
841 }
842 }
843
844 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
845 return true;
846 }
847
848 return false;
849}
850
851bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
852 if (VisitDeclaratorDecl(D))
853 return true;
854
855 if (Expr *BitWidth = D->getBitWidth())
856 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
857
858 return false;
859}
860
861bool CursorVisitor::VisitVarDecl(VarDecl *D) {
862 if (VisitDeclaratorDecl(D))
863 return true;
864
865 if (Expr *Init = D->getInit())
866 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
867
868 return false;
869}
870
871bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
872 if (VisitDeclaratorDecl(D))
873 return true;
874
875 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
876 if (Expr *DefArg = D->getDefaultArgument())
877 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
878
879 return false;
880}
881
882bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
883 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
884 // before visiting these template parameters.
885 if (VisitTemplateParameters(D->getTemplateParameters()))
886 return true;
887
888 return VisitFunctionDecl(D->getTemplatedDecl());
889}
890
891bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
892 // FIXME: Visit the "outer" template parameter lists on the TagDecl
893 // before visiting these template parameters.
894 if (VisitTemplateParameters(D->getTemplateParameters()))
895 return true;
896
897 return VisitCXXRecordDecl(D->getTemplatedDecl());
898}
899
900bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
901 if (VisitTemplateParameters(D->getTemplateParameters()))
902 return true;
903
904 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
905 VisitTemplateArgumentLoc(D->getDefaultArgument()))
906 return true;
907
908 return false;
909}
910
911bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000912 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000913 if (Visit(TSInfo->getTypeLoc()))
914 return true;
915
Aaron Ballman43b68be2014-03-07 17:50:17 +0000916 for (const auto *P : ND->params()) {
917 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000918 return true;
919 }
920
921 if (ND->isThisDeclarationADefinition() &&
922 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
923 return true;
924
925 return false;
926}
927
928template <typename DeclIt>
929static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
930 SourceManager &SM, SourceLocation EndLoc,
931 SmallVectorImpl<Decl *> &Decls) {
932 DeclIt next = *DI_current;
933 while (++next != DE_current) {
934 Decl *D_next = *next;
935 if (!D_next)
936 break;
937 SourceLocation L = D_next->getLocStart();
938 if (!L.isValid())
939 break;
940 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
941 *DI_current = next;
942 Decls.push_back(D_next);
943 continue;
944 }
945 break;
946 }
947}
948
Guy Benyei11169dd2012-12-18 14:30:41 +0000949bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
950 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
951 // an @implementation can lexically contain Decls that are not properly
952 // nested in the AST. When we identify such cases, we need to retrofit
953 // this nesting here.
954 if (!DI_current && !FileDI_current)
955 return VisitDeclContext(D);
956
957 // Scan the Decls that immediately come after the container
958 // in the current DeclContext. If any fall within the
959 // container's lexical region, stash them into a vector
960 // for later processing.
961 SmallVector<Decl *, 24> DeclsInContainer;
962 SourceLocation EndLoc = D->getSourceRange().getEnd();
963 SourceManager &SM = AU->getSourceManager();
964 if (EndLoc.isValid()) {
965 if (DI_current) {
966 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
967 DeclsInContainer);
968 } else {
969 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
970 DeclsInContainer);
971 }
972 }
973
974 // The common case.
975 if (DeclsInContainer.empty())
976 return VisitDeclContext(D);
977
978 // Get all the Decls in the DeclContext, and sort them with the
979 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000980 for (auto *SubDecl : D->decls()) {
981 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
982 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000983 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000984 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000985 }
986
987 // Now sort the Decls so that they appear in lexical order.
988 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000989 [&SM](Decl *A, Decl *B) {
990 SourceLocation L_A = A->getLocStart();
991 SourceLocation L_B = B->getLocStart();
992 assert(L_A.isValid() && L_B.isValid());
993 return SM.isBeforeInTranslationUnit(L_A, L_B);
994 });
Guy Benyei11169dd2012-12-18 14:30:41 +0000995
996 // Now visit the decls.
997 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
998 E = DeclsInContainer.end(); I != E; ++I) {
999 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001000 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001001 if (!V.hasValue())
1002 continue;
1003 if (!V.getValue())
1004 return false;
1005 if (Visit(Cursor, true))
1006 return true;
1007 }
1008 return false;
1009}
1010
1011bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1012 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1013 TU)))
1014 return true;
1015
1016 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1017 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1018 E = ND->protocol_end(); I != E; ++I, ++PL)
1019 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1020 return true;
1021
1022 return VisitObjCContainerDecl(ND);
1023}
1024
1025bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1026 if (!PID->isThisDeclarationADefinition())
1027 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1028
1029 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1030 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1031 E = PID->protocol_end(); I != E; ++I, ++PL)
1032 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1033 return true;
1034
1035 return VisitObjCContainerDecl(PID);
1036}
1037
1038bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1039 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1040 return true;
1041
1042 // FIXME: This implements a workaround with @property declarations also being
1043 // installed in the DeclContext for the @interface. Eventually this code
1044 // should be removed.
1045 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1046 if (!CDecl || !CDecl->IsClassExtension())
1047 return false;
1048
1049 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1050 if (!ID)
1051 return false;
1052
1053 IdentifierInfo *PropertyId = PD->getIdentifier();
1054 ObjCPropertyDecl *prevDecl =
1055 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1056
1057 if (!prevDecl)
1058 return false;
1059
1060 // Visit synthesized methods since they will be skipped when visiting
1061 // the @interface.
1062 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1063 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1064 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1065 return true;
1066
1067 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1068 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1069 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1070 return true;
1071
1072 return false;
1073}
1074
1075bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1076 if (!D->isThisDeclarationADefinition()) {
1077 // Forward declaration is treated like a reference.
1078 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1079 }
1080
1081 // Issue callbacks for super class.
1082 if (D->getSuperClass() &&
1083 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1084 D->getSuperClassLoc(),
1085 TU)))
1086 return true;
1087
1088 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1089 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1090 E = D->protocol_end(); I != E; ++I, ++PL)
1091 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1092 return true;
1093
1094 return VisitObjCContainerDecl(D);
1095}
1096
1097bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1098 return VisitObjCContainerDecl(D);
1099}
1100
1101bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1102 // 'ID' could be null when dealing with invalid code.
1103 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1104 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1105 return true;
1106
1107 return VisitObjCImplDecl(D);
1108}
1109
1110bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1111#if 0
1112 // Issue callbacks for super class.
1113 // FIXME: No source location information!
1114 if (D->getSuperClass() &&
1115 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1116 D->getSuperClassLoc(),
1117 TU)))
1118 return true;
1119#endif
1120
1121 return VisitObjCImplDecl(D);
1122}
1123
1124bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1125 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1126 if (PD->isIvarNameSpecified())
1127 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1128
1129 return false;
1130}
1131
1132bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1133 return VisitDeclContext(D);
1134}
1135
1136bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1137 // Visit nested-name-specifier.
1138 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1139 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1140 return true;
1141
1142 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1143 D->getTargetNameLoc(), TU));
1144}
1145
1146bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1147 // Visit nested-name-specifier.
1148 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1149 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1150 return true;
1151 }
1152
1153 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1154 return true;
1155
1156 return VisitDeclarationNameInfo(D->getNameInfo());
1157}
1158
1159bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1160 // Visit nested-name-specifier.
1161 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1162 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1163 return true;
1164
1165 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1166 D->getIdentLocation(), TU));
1167}
1168
1169bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1170 // Visit nested-name-specifier.
1171 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1172 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1173 return true;
1174 }
1175
1176 return VisitDeclarationNameInfo(D->getNameInfo());
1177}
1178
1179bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1180 UnresolvedUsingTypenameDecl *D) {
1181 // Visit nested-name-specifier.
1182 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1183 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1184 return true;
1185
1186 return false;
1187}
1188
1189bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1190 switch (Name.getName().getNameKind()) {
1191 case clang::DeclarationName::Identifier:
1192 case clang::DeclarationName::CXXLiteralOperatorName:
1193 case clang::DeclarationName::CXXOperatorName:
1194 case clang::DeclarationName::CXXUsingDirective:
1195 return false;
1196
1197 case clang::DeclarationName::CXXConstructorName:
1198 case clang::DeclarationName::CXXDestructorName:
1199 case clang::DeclarationName::CXXConversionFunctionName:
1200 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1201 return Visit(TSInfo->getTypeLoc());
1202 return false;
1203
1204 case clang::DeclarationName::ObjCZeroArgSelector:
1205 case clang::DeclarationName::ObjCOneArgSelector:
1206 case clang::DeclarationName::ObjCMultiArgSelector:
1207 // FIXME: Per-identifier location info?
1208 return false;
1209 }
1210
1211 llvm_unreachable("Invalid DeclarationName::Kind!");
1212}
1213
1214bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1215 SourceRange Range) {
1216 // FIXME: This whole routine is a hack to work around the lack of proper
1217 // source information in nested-name-specifiers (PR5791). Since we do have
1218 // a beginning source location, we can visit the first component of the
1219 // nested-name-specifier, if it's a single-token component.
1220 if (!NNS)
1221 return false;
1222
1223 // Get the first component in the nested-name-specifier.
1224 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1225 NNS = Prefix;
1226
1227 switch (NNS->getKind()) {
1228 case NestedNameSpecifier::Namespace:
1229 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1230 TU));
1231
1232 case NestedNameSpecifier::NamespaceAlias:
1233 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1234 Range.getBegin(), TU));
1235
1236 case NestedNameSpecifier::TypeSpec: {
1237 // If the type has a form where we know that the beginning of the source
1238 // range matches up with a reference cursor. Visit the appropriate reference
1239 // cursor.
1240 const Type *T = NNS->getAsType();
1241 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1242 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1243 if (const TagType *Tag = dyn_cast<TagType>(T))
1244 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1245 if (const TemplateSpecializationType *TST
1246 = dyn_cast<TemplateSpecializationType>(T))
1247 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1248 break;
1249 }
1250
1251 case NestedNameSpecifier::TypeSpecWithTemplate:
1252 case NestedNameSpecifier::Global:
1253 case NestedNameSpecifier::Identifier:
1254 break;
1255 }
1256
1257 return false;
1258}
1259
1260bool
1261CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1262 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1263 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1264 Qualifiers.push_back(Qualifier);
1265
1266 while (!Qualifiers.empty()) {
1267 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1268 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1269 switch (NNS->getKind()) {
1270 case NestedNameSpecifier::Namespace:
1271 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1272 Q.getLocalBeginLoc(),
1273 TU)))
1274 return true;
1275
1276 break;
1277
1278 case NestedNameSpecifier::NamespaceAlias:
1279 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1280 Q.getLocalBeginLoc(),
1281 TU)))
1282 return true;
1283
1284 break;
1285
1286 case NestedNameSpecifier::TypeSpec:
1287 case NestedNameSpecifier::TypeSpecWithTemplate:
1288 if (Visit(Q.getTypeLoc()))
1289 return true;
1290
1291 break;
1292
1293 case NestedNameSpecifier::Global:
1294 case NestedNameSpecifier::Identifier:
1295 break;
1296 }
1297 }
1298
1299 return false;
1300}
1301
1302bool CursorVisitor::VisitTemplateParameters(
1303 const TemplateParameterList *Params) {
1304 if (!Params)
1305 return false;
1306
1307 for (TemplateParameterList::const_iterator P = Params->begin(),
1308 PEnd = Params->end();
1309 P != PEnd; ++P) {
1310 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1311 return true;
1312 }
1313
1314 return false;
1315}
1316
1317bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1318 switch (Name.getKind()) {
1319 case TemplateName::Template:
1320 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1321
1322 case TemplateName::OverloadedTemplate:
1323 // Visit the overloaded template set.
1324 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1325 return true;
1326
1327 return false;
1328
1329 case TemplateName::DependentTemplate:
1330 // FIXME: Visit nested-name-specifier.
1331 return false;
1332
1333 case TemplateName::QualifiedTemplate:
1334 // FIXME: Visit nested-name-specifier.
1335 return Visit(MakeCursorTemplateRef(
1336 Name.getAsQualifiedTemplateName()->getDecl(),
1337 Loc, TU));
1338
1339 case TemplateName::SubstTemplateTemplateParm:
1340 return Visit(MakeCursorTemplateRef(
1341 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1342 Loc, TU));
1343
1344 case TemplateName::SubstTemplateTemplateParmPack:
1345 return Visit(MakeCursorTemplateRef(
1346 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1347 Loc, TU));
1348 }
1349
1350 llvm_unreachable("Invalid TemplateName::Kind!");
1351}
1352
1353bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1354 switch (TAL.getArgument().getKind()) {
1355 case TemplateArgument::Null:
1356 case TemplateArgument::Integral:
1357 case TemplateArgument::Pack:
1358 return false;
1359
1360 case TemplateArgument::Type:
1361 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1362 return Visit(TSInfo->getTypeLoc());
1363 return false;
1364
1365 case TemplateArgument::Declaration:
1366 if (Expr *E = TAL.getSourceDeclExpression())
1367 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1368 return false;
1369
1370 case TemplateArgument::NullPtr:
1371 if (Expr *E = TAL.getSourceNullPtrExpression())
1372 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1373 return false;
1374
1375 case TemplateArgument::Expression:
1376 if (Expr *E = TAL.getSourceExpression())
1377 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1378 return false;
1379
1380 case TemplateArgument::Template:
1381 case TemplateArgument::TemplateExpansion:
1382 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1383 return true;
1384
1385 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1386 TAL.getTemplateNameLoc());
1387 }
1388
1389 llvm_unreachable("Invalid TemplateArgument::Kind!");
1390}
1391
1392bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1393 return VisitDeclContext(D);
1394}
1395
1396bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1397 return Visit(TL.getUnqualifiedLoc());
1398}
1399
1400bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1401 ASTContext &Context = AU->getASTContext();
1402
1403 // Some builtin types (such as Objective-C's "id", "sel", and
1404 // "Class") have associated declarations. Create cursors for those.
1405 QualType VisitType;
1406 switch (TL.getTypePtr()->getKind()) {
1407
1408 case BuiltinType::Void:
1409 case BuiltinType::NullPtr:
1410 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001411 case BuiltinType::OCLImage1d:
1412 case BuiltinType::OCLImage1dArray:
1413 case BuiltinType::OCLImage1dBuffer:
1414 case BuiltinType::OCLImage2d:
1415 case BuiltinType::OCLImage2dArray:
1416 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001417 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001418 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001419#define BUILTIN_TYPE(Id, SingletonId)
1420#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1421#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1422#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1423#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1424#include "clang/AST/BuiltinTypes.def"
1425 break;
1426
1427 case BuiltinType::ObjCId:
1428 VisitType = Context.getObjCIdType();
1429 break;
1430
1431 case BuiltinType::ObjCClass:
1432 VisitType = Context.getObjCClassType();
1433 break;
1434
1435 case BuiltinType::ObjCSel:
1436 VisitType = Context.getObjCSelType();
1437 break;
1438 }
1439
1440 if (!VisitType.isNull()) {
1441 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1442 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1443 TU));
1444 }
1445
1446 return false;
1447}
1448
1449bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1450 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1451}
1452
1453bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1454 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1455}
1456
1457bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1458 if (TL.isDefinition())
1459 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1460
1461 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1462}
1463
1464bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1465 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1466}
1467
1468bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1469 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1470 return true;
1471
1472 return false;
1473}
1474
1475bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1476 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1477 return true;
1478
1479 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1480 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1481 TU)))
1482 return true;
1483 }
1484
1485 return false;
1486}
1487
1488bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1489 return Visit(TL.getPointeeLoc());
1490}
1491
1492bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1493 return Visit(TL.getInnerLoc());
1494}
1495
1496bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1497 return Visit(TL.getPointeeLoc());
1498}
1499
1500bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1501 return Visit(TL.getPointeeLoc());
1502}
1503
1504bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1505 return Visit(TL.getPointeeLoc());
1506}
1507
1508bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1509 return Visit(TL.getPointeeLoc());
1510}
1511
1512bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1513 return Visit(TL.getPointeeLoc());
1514}
1515
1516bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1517 return Visit(TL.getModifiedLoc());
1518}
1519
1520bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1521 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001522 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001523 return true;
1524
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001525 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1526 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001527 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1528 return true;
1529
1530 return false;
1531}
1532
1533bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1534 if (Visit(TL.getElementLoc()))
1535 return true;
1536
1537 if (Expr *Size = TL.getSizeExpr())
1538 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1539
1540 return false;
1541}
1542
Reid Kleckner8a365022013-06-24 17:51:48 +00001543bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1544 return Visit(TL.getOriginalLoc());
1545}
1546
Reid Kleckner0503a872013-12-05 01:23:43 +00001547bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1548 return Visit(TL.getOriginalLoc());
1549}
1550
Guy Benyei11169dd2012-12-18 14:30:41 +00001551bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1552 TemplateSpecializationTypeLoc TL) {
1553 // Visit the template name.
1554 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1555 TL.getTemplateNameLoc()))
1556 return true;
1557
1558 // Visit the template arguments.
1559 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1560 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1561 return true;
1562
1563 return false;
1564}
1565
1566bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1567 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1568}
1569
1570bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1571 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1572 return Visit(TSInfo->getTypeLoc());
1573
1574 return false;
1575}
1576
1577bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1578 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1579 return Visit(TSInfo->getTypeLoc());
1580
1581 return false;
1582}
1583
1584bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1585 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1586 return true;
1587
1588 return false;
1589}
1590
1591bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1592 DependentTemplateSpecializationTypeLoc TL) {
1593 // Visit the nested-name-specifier, if there is one.
1594 if (TL.getQualifierLoc() &&
1595 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1596 return true;
1597
1598 // Visit the template arguments.
1599 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1600 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1601 return true;
1602
1603 return false;
1604}
1605
1606bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1607 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1608 return true;
1609
1610 return Visit(TL.getNamedTypeLoc());
1611}
1612
1613bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1614 return Visit(TL.getPatternLoc());
1615}
1616
1617bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1618 if (Expr *E = TL.getUnderlyingExpr())
1619 return Visit(MakeCXCursor(E, StmtParent, TU));
1620
1621 return false;
1622}
1623
1624bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1625 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1626}
1627
1628bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1629 return Visit(TL.getValueLoc());
1630}
1631
1632#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1633bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1634 return Visit##PARENT##Loc(TL); \
1635}
1636
1637DEFAULT_TYPELOC_IMPL(Complex, Type)
1638DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1639DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1640DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1641DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1642DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1643DEFAULT_TYPELOC_IMPL(Vector, Type)
1644DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1645DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1646DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1647DEFAULT_TYPELOC_IMPL(Record, TagType)
1648DEFAULT_TYPELOC_IMPL(Enum, TagType)
1649DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1650DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1651DEFAULT_TYPELOC_IMPL(Auto, Type)
1652
1653bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1654 // Visit the nested-name-specifier, if present.
1655 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1656 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1657 return true;
1658
1659 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001660 for (const auto &I : D->bases()) {
1661 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001662 return true;
1663 }
1664 }
1665
1666 return VisitTagDecl(D);
1667}
1668
1669bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001670 for (const auto *I : D->attrs())
1671 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001672 return true;
1673
1674 return false;
1675}
1676
1677//===----------------------------------------------------------------------===//
1678// Data-recursive visitor methods.
1679//===----------------------------------------------------------------------===//
1680
1681namespace {
1682#define DEF_JOB(NAME, DATA, KIND)\
1683class NAME : public VisitorJob {\
1684public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001685 NAME(const DATA *d, CXCursor parent) : \
1686 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001687 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001688 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001689};
1690
1691DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1692DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1693DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1694DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1695DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1696 ExplicitTemplateArgsVisitKind)
1697DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1698DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1699DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1700#undef DEF_JOB
1701
1702class DeclVisit : public VisitorJob {
1703public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001704 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001705 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001706 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001707 static bool classof(const VisitorJob *VJ) {
1708 return VJ->getKind() == DeclVisitKind;
1709 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001710 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001711 bool isFirst() const { return data[1] ? true : false; }
1712};
1713class TypeLocVisit : public VisitorJob {
1714public:
1715 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1716 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1717 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1718
1719 static bool classof(const VisitorJob *VJ) {
1720 return VJ->getKind() == TypeLocVisitKind;
1721 }
1722
1723 TypeLoc get() const {
1724 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001725 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001726 }
1727};
1728
1729class LabelRefVisit : public VisitorJob {
1730public:
1731 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1732 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1733 labelLoc.getPtrEncoding()) {}
1734
1735 static bool classof(const VisitorJob *VJ) {
1736 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1737 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001738 const LabelDecl *get() const {
1739 return static_cast<const LabelDecl *>(data[0]);
1740 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001741 SourceLocation getLoc() const {
1742 return SourceLocation::getFromPtrEncoding(data[1]); }
1743};
1744
1745class NestedNameSpecifierLocVisit : public VisitorJob {
1746public:
1747 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1748 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1749 Qualifier.getNestedNameSpecifier(),
1750 Qualifier.getOpaqueData()) { }
1751
1752 static bool classof(const VisitorJob *VJ) {
1753 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1754 }
1755
1756 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001757 return NestedNameSpecifierLoc(
1758 const_cast<NestedNameSpecifier *>(
1759 static_cast<const NestedNameSpecifier *>(data[0])),
1760 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001761 }
1762};
1763
1764class DeclarationNameInfoVisit : public VisitorJob {
1765public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001766 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001767 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001768 static bool classof(const VisitorJob *VJ) {
1769 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1770 }
1771 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001772 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001773 switch (S->getStmtClass()) {
1774 default:
1775 llvm_unreachable("Unhandled Stmt");
1776 case clang::Stmt::MSDependentExistsStmtClass:
1777 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1778 case Stmt::CXXDependentScopeMemberExprClass:
1779 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1780 case Stmt::DependentScopeDeclRefExprClass:
1781 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1782 }
1783 }
1784};
1785class MemberRefVisit : public VisitorJob {
1786public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001787 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001788 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1789 L.getPtrEncoding()) {}
1790 static bool classof(const VisitorJob *VJ) {
1791 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1792 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001793 const FieldDecl *get() const {
1794 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001795 }
1796 SourceLocation getLoc() const {
1797 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1798 }
1799};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001800class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001801 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001802 VisitorWorkList &WL;
1803 CXCursor Parent;
1804public:
1805 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1806 : WL(wl), Parent(parent) {}
1807
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001808 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1809 void VisitBlockExpr(const BlockExpr *B);
1810 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1811 void VisitCompoundStmt(const CompoundStmt *S);
1812 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1813 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1814 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1815 void VisitCXXNewExpr(const CXXNewExpr *E);
1816 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1817 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1818 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1819 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1820 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1821 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1822 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1823 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1824 void VisitDeclRefExpr(const DeclRefExpr *D);
1825 void VisitDeclStmt(const DeclStmt *S);
1826 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1827 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1828 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1829 void VisitForStmt(const ForStmt *FS);
1830 void VisitGotoStmt(const GotoStmt *GS);
1831 void VisitIfStmt(const IfStmt *If);
1832 void VisitInitListExpr(const InitListExpr *IE);
1833 void VisitMemberExpr(const MemberExpr *M);
1834 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1835 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1836 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1837 void VisitOverloadExpr(const OverloadExpr *E);
1838 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1839 void VisitStmt(const Stmt *S);
1840 void VisitSwitchStmt(const SwitchStmt *S);
1841 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001842 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1843 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1844 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1845 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1846 void VisitVAArgExpr(const VAArgExpr *E);
1847 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1848 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1849 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1850 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001851 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1852 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001853 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001854
Guy Benyei11169dd2012-12-18 14:30:41 +00001855private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001856 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001857 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1858 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001859 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1860 void AddStmt(const Stmt *S);
1861 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001862 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001863 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001864 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001865};
1866} // end anonyous namespace
1867
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001868void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001869 // 'S' should always be non-null, since it comes from the
1870 // statement we are visiting.
1871 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1872}
1873
1874void
1875EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1876 if (Qualifier)
1877 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1878}
1879
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001880void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001881 if (S)
1882 WL.push_back(StmtVisit(S, Parent));
1883}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001884void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001885 if (D)
1886 WL.push_back(DeclVisit(D, Parent, isFirst));
1887}
1888void EnqueueVisitor::
1889 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1890 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001891 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001892}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001893void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001894 if (D)
1895 WL.push_back(MemberRefVisit(D, L, Parent));
1896}
1897void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1898 if (TI)
1899 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1900 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001901void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001902 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001903 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001904 AddStmt(*Child);
1905 }
1906 if (size == WL.size())
1907 return;
1908 // Now reverse the entries we just added. This will match the DFS
1909 // ordering performed by the worklist.
1910 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1911 std::reverse(I, E);
1912}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001913namespace {
1914class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1915 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001916 /// \brief Process clauses with list of variables.
1917 template <typename T>
1918 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001919public:
1920 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1921#define OPENMP_CLAUSE(Name, Class) \
1922 void Visit##Class(const Class *C);
1923#include "clang/Basic/OpenMPKinds.def"
1924};
1925
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001926void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1927 Visitor->AddStmt(C->getCondition());
1928}
1929
Alexey Bataev568a8332014-03-06 06:15:19 +00001930void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1931 Visitor->AddStmt(C->getNumThreads());
1932}
1933
Alexey Bataev62c87d22014-03-21 04:51:18 +00001934void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1935 Visitor->AddStmt(C->getSafelen());
1936}
1937
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001938void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001939
1940template<typename T>
1941void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001942 for (const auto *I : Node->varlists())
1943 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001944}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001945
1946void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001947 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001948}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001949void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1950 const OMPFirstprivateClause *C) {
1951 VisitOMPClauseList(C);
1952}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001953void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001954 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001955}
Alexander Musman8dba6642014-04-22 13:09:42 +00001956void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
1957 VisitOMPClauseList(C);
1958 Visitor->AddStmt(C->getStep());
1959}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00001960void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
1961 VisitOMPClauseList(C);
1962}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001963}
Alexey Bataev756c1962013-09-24 03:17:45 +00001964
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001965void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1966 unsigned size = WL.size();
1967 OMPClauseEnqueue Visitor(this);
1968 Visitor.Visit(S);
1969 if (size == WL.size())
1970 return;
1971 // Now reverse the entries we just added. This will match the DFS
1972 // ordering performed by the worklist.
1973 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1974 std::reverse(I, E);
1975}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001976void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001977 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1978}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001979void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001980 AddDecl(B->getBlockDecl());
1981}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001982void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001983 EnqueueChildren(E);
1984 AddTypeLoc(E->getTypeSourceInfo());
1985}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001986void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1987 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001988 E = S->body_rend(); I != E; ++I) {
1989 AddStmt(*I);
1990 }
1991}
1992void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001993VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001994 AddStmt(S->getSubStmt());
1995 AddDeclarationNameInfo(S);
1996 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1997 AddNestedNameSpecifierLoc(QualifierLoc);
1998}
1999
2000void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002001VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002002 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2003 AddDeclarationNameInfo(E);
2004 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2005 AddNestedNameSpecifierLoc(QualifierLoc);
2006 if (!E->isImplicitAccess())
2007 AddStmt(E->getBase());
2008}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002009void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002010 // Enqueue the initializer , if any.
2011 AddStmt(E->getInitializer());
2012 // Enqueue the array size, if any.
2013 AddStmt(E->getArraySize());
2014 // Enqueue the allocated type.
2015 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2016 // Enqueue the placement arguments.
2017 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2018 AddStmt(E->getPlacementArg(I-1));
2019}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002020void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002021 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2022 AddStmt(CE->getArg(I-1));
2023 AddStmt(CE->getCallee());
2024 AddStmt(CE->getArg(0));
2025}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002026void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2027 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002028 // Visit the name of the type being destroyed.
2029 AddTypeLoc(E->getDestroyedTypeInfo());
2030 // Visit the scope type that looks disturbingly like the nested-name-specifier
2031 // but isn't.
2032 AddTypeLoc(E->getScopeTypeInfo());
2033 // Visit the nested-name-specifier.
2034 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2035 AddNestedNameSpecifierLoc(QualifierLoc);
2036 // Visit base expression.
2037 AddStmt(E->getBase());
2038}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002039void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2040 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002041 AddTypeLoc(E->getTypeSourceInfo());
2042}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002043void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2044 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002045 EnqueueChildren(E);
2046 AddTypeLoc(E->getTypeSourceInfo());
2047}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002048void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002049 EnqueueChildren(E);
2050 if (E->isTypeOperand())
2051 AddTypeLoc(E->getTypeOperandSourceInfo());
2052}
2053
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002054void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2055 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002056 EnqueueChildren(E);
2057 AddTypeLoc(E->getTypeSourceInfo());
2058}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002059void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002060 EnqueueChildren(E);
2061 if (E->isTypeOperand())
2062 AddTypeLoc(E->getTypeOperandSourceInfo());
2063}
2064
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002065void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002066 EnqueueChildren(S);
2067 AddDecl(S->getExceptionDecl());
2068}
2069
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002070void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002071 if (DR->hasExplicitTemplateArgs()) {
2072 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2073 }
2074 WL.push_back(DeclRefExprParts(DR, Parent));
2075}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002076void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2077 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002078 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2079 AddDeclarationNameInfo(E);
2080 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2081}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002082void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002083 unsigned size = WL.size();
2084 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002085 for (const auto *D : S->decls()) {
2086 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002087 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
Ahmed Charlesb8984322014-03-07 20:03:18 +00002729 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2730 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002731
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
Ahmed Charlesb8984322014-03-07 20:03:18 +00002744 std::unique_ptr<std::vector<const char *>> Args(
2745 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002746
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();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002785 std::unique_ptr<ASTUnit> ErrUnit;
2786 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002787 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002788 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2789 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2790 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2791 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2792 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2793 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002794
2795 if (NumErrors != Diags->getClient()->getNumErrors()) {
2796 // Make sure to check that 'Unit' is non-NULL.
2797 if (CXXIdx->getDisplayDiagnostics())
2798 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2799 }
2800
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002801 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2802 PTUI->result = CXError_ASTReadError;
2803 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002804 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002805 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2806 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002807}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002808
2809CXTranslationUnit
2810clang_parseTranslationUnit(CXIndex CIdx,
2811 const char *source_filename,
2812 const char *const *command_line_args,
2813 int num_command_line_args,
2814 struct CXUnsavedFile *unsaved_files,
2815 unsigned num_unsaved_files,
2816 unsigned options) {
2817 CXTranslationUnit TU;
2818 enum CXErrorCode Result = clang_parseTranslationUnit2(
2819 CIdx, source_filename, command_line_args, num_command_line_args,
2820 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002821 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002822 assert((TU && Result == CXError_Success) ||
2823 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002824 return TU;
2825}
2826
2827enum CXErrorCode clang_parseTranslationUnit2(
2828 CXIndex CIdx,
2829 const char *source_filename,
2830 const char *const *command_line_args,
2831 int num_command_line_args,
2832 struct CXUnsavedFile *unsaved_files,
2833 unsigned num_unsaved_files,
2834 unsigned options,
2835 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002836 LOG_FUNC_SECTION {
2837 *Log << source_filename << ": ";
2838 for (int i = 0; i != num_command_line_args; ++i)
2839 *Log << command_line_args[i] << " ";
2840 }
2841
Guy Benyei11169dd2012-12-18 14:30:41 +00002842 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2843 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002844 num_unsaved_files, options, out_TU,
2845 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002846 llvm::CrashRecoveryContext CRC;
2847
2848 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2849 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2850 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2851 fprintf(stderr, " 'command_line_args' : [");
2852 for (int i = 0; i != num_command_line_args; ++i) {
2853 if (i)
2854 fprintf(stderr, ", ");
2855 fprintf(stderr, "'%s'", command_line_args[i]);
2856 }
2857 fprintf(stderr, "],\n");
2858 fprintf(stderr, " 'unsaved_files' : [");
2859 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2860 if (i)
2861 fprintf(stderr, ", ");
2862 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2863 unsaved_files[i].Length);
2864 }
2865 fprintf(stderr, "],\n");
2866 fprintf(stderr, " 'options' : %d,\n", options);
2867 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002868
2869 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002870 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002871 if (CXTranslationUnit *TU = PTUI.out_TU)
2872 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002873 }
2874
2875 return PTUI.result;
2876}
2877
2878unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2879 return CXSaveTranslationUnit_None;
2880}
2881
2882namespace {
2883
2884struct SaveTranslationUnitInfo {
2885 CXTranslationUnit TU;
2886 const char *FileName;
2887 unsigned options;
2888 CXSaveError result;
2889};
2890
2891}
2892
2893static void clang_saveTranslationUnit_Impl(void *UserData) {
2894 SaveTranslationUnitInfo *STUI =
2895 static_cast<SaveTranslationUnitInfo*>(UserData);
2896
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002897 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002898 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2899 setThreadBackgroundPriority();
2900
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002901 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002902 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2903}
2904
2905int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2906 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002907 LOG_FUNC_SECTION {
2908 *Log << TU << ' ' << FileName;
2909 }
2910
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002911 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002912 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002913 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002914 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002915
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002916 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002917 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2918 if (!CXXUnit->hasSema())
2919 return CXSaveError_InvalidTU;
2920
2921 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2922
2923 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2924 getenv("LIBCLANG_NOTHREADS")) {
2925 clang_saveTranslationUnit_Impl(&STUI);
2926
2927 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2928 PrintLibclangResourceUsage(TU);
2929
2930 return STUI.result;
2931 }
2932
2933 // We have an AST that has invalid nodes due to compiler errors.
2934 // Use a crash recovery thread for protection.
2935
2936 llvm::CrashRecoveryContext CRC;
2937
2938 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2939 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2940 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2941 fprintf(stderr, " 'options' : %d,\n", options);
2942 fprintf(stderr, "}\n");
2943
2944 return CXSaveError_Unknown;
2945
2946 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2947 PrintLibclangResourceUsage(TU);
2948 }
2949
2950 return STUI.result;
2951}
2952
2953void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2954 if (CTUnit) {
2955 // If the translation unit has been marked as unsafe to free, just discard
2956 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002957 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2958 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002959 return;
2960
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002961 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002962 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002963 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2964 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002965 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002966 delete CTUnit;
2967 }
2968}
2969
2970unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2971 return CXReparse_None;
2972}
2973
2974struct ReparseTranslationUnitInfo {
2975 CXTranslationUnit TU;
2976 unsigned num_unsaved_files;
2977 struct CXUnsavedFile *unsaved_files;
2978 unsigned options;
2979 int result;
2980};
2981
2982static void clang_reparseTranslationUnit_Impl(void *UserData) {
2983 ReparseTranslationUnitInfo *RTUI =
2984 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002985 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002986
Guy Benyei11169dd2012-12-18 14:30:41 +00002987 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002988 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2989 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2990 unsigned options = RTUI->options;
2991 (void) options;
2992
2993 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002994 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002995 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002996 RTUI->result = CXError_InvalidArguments;
2997 return;
2998 }
2999 if (unsaved_files == NULL && num_unsaved_files != 0) {
3000 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003001 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003002 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003003
3004 // Reset the associated diagnostics.
3005 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3006 TU->Diagnostics = 0;
3007
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003008 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003009 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3010 setThreadBackgroundPriority();
3011
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003012 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003013 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003014
3015 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3016 new std::vector<ASTUnit::RemappedFile>());
3017
Guy Benyei11169dd2012-12-18 14:30:41 +00003018 // Recover resources if we crash before exiting this function.
3019 llvm::CrashRecoveryContextCleanupRegistrar<
3020 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3021
3022 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3023 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3024 const llvm::MemoryBuffer *Buffer
3025 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3026 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3027 Buffer));
3028 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003029
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003030 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003031 RTUI->result = CXError_Success;
3032 else if (isASTReadError(CXXUnit))
3033 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003034}
3035
3036int clang_reparseTranslationUnit(CXTranslationUnit TU,
3037 unsigned num_unsaved_files,
3038 struct CXUnsavedFile *unsaved_files,
3039 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003040 LOG_FUNC_SECTION {
3041 *Log << TU;
3042 }
3043
Guy Benyei11169dd2012-12-18 14:30:41 +00003044 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003045 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003046
3047 if (getenv("LIBCLANG_NOTHREADS")) {
3048 clang_reparseTranslationUnit_Impl(&RTUI);
3049 return RTUI.result;
3050 }
3051
3052 llvm::CrashRecoveryContext CRC;
3053
3054 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3055 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003056 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003057 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003058 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3059 PrintLibclangResourceUsage(TU);
3060
3061 return RTUI.result;
3062}
3063
3064
3065CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003066 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003067 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003068 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003069 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003070
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003071 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003072 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003073}
3074
3075CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003076 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003077 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003078 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003079 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003080
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003081 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003082 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3083}
3084
3085} // end: extern "C"
3086
3087//===----------------------------------------------------------------------===//
3088// CXFile Operations.
3089//===----------------------------------------------------------------------===//
3090
3091extern "C" {
3092CXString clang_getFileName(CXFile SFile) {
3093 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003094 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003095
3096 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003097 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003098}
3099
3100time_t clang_getFileTime(CXFile SFile) {
3101 if (!SFile)
3102 return 0;
3103
3104 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3105 return FEnt->getModificationTime();
3106}
3107
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003108CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003109 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003110 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003111 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003112 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003113
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003114 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003115
3116 FileManager &FMgr = CXXUnit->getFileManager();
3117 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3118}
3119
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003120unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3121 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003122 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003123 LOG_BAD_TU(TU);
3124 return 0;
3125 }
3126
3127 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003128 return 0;
3129
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003130 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003131 FileEntry *FEnt = static_cast<FileEntry *>(file);
3132 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3133 .isFileMultipleIncludeGuarded(FEnt);
3134}
3135
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003136int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3137 if (!file || !outID)
3138 return 1;
3139
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003140 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003141 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3142 outID->data[0] = ID.getDevice();
3143 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003144 outID->data[2] = FEnt->getModificationTime();
3145 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003146}
3147
Guy Benyei11169dd2012-12-18 14:30:41 +00003148} // end: extern "C"
3149
3150//===----------------------------------------------------------------------===//
3151// CXCursor Operations.
3152//===----------------------------------------------------------------------===//
3153
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003154static const Decl *getDeclFromExpr(const Stmt *E) {
3155 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003156 return getDeclFromExpr(CE->getSubExpr());
3157
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003158 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003159 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003160 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003161 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003162 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003163 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003164 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003165 if (PRE->isExplicitProperty())
3166 return PRE->getExplicitProperty();
3167 // It could be messaging both getter and setter as in:
3168 // ++myobj.myprop;
3169 // in which case prefer to associate the setter since it is less obvious
3170 // from inspecting the source that the setter is going to get called.
3171 if (PRE->isMessagingSetter())
3172 return PRE->getImplicitPropertySetter();
3173 return PRE->getImplicitPropertyGetter();
3174 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003175 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003176 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003177 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003178 if (Expr *Src = OVE->getSourceExpr())
3179 return getDeclFromExpr(Src);
3180
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003181 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003182 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003183 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003184 if (!CE->isElidable())
3185 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003186 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003187 return OME->getMethodDecl();
3188
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003189 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003190 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003191 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003192 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3193 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003194 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003195 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3196 isa<ParmVarDecl>(SizeOfPack->getPack()))
3197 return SizeOfPack->getPack();
3198
3199 return 0;
3200}
3201
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003202static SourceLocation getLocationFromExpr(const Expr *E) {
3203 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003204 return getLocationFromExpr(CE->getSubExpr());
3205
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003206 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003207 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003208 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003209 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003210 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003211 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003212 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003213 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003214 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003215 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003216 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003217 return PropRef->getLocation();
3218
3219 return E->getLocStart();
3220}
3221
3222extern "C" {
3223
3224unsigned clang_visitChildren(CXCursor parent,
3225 CXCursorVisitor visitor,
3226 CXClientData client_data) {
3227 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3228 /*VisitPreprocessorLast=*/false);
3229 return CursorVis.VisitChildren(parent);
3230}
3231
3232#ifndef __has_feature
3233#define __has_feature(x) 0
3234#endif
3235#if __has_feature(blocks)
3236typedef enum CXChildVisitResult
3237 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3238
3239static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3240 CXClientData client_data) {
3241 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3242 return block(cursor, parent);
3243}
3244#else
3245// If we are compiled with a compiler that doesn't have native blocks support,
3246// define and call the block manually, so the
3247typedef struct _CXChildVisitResult
3248{
3249 void *isa;
3250 int flags;
3251 int reserved;
3252 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3253 CXCursor);
3254} *CXCursorVisitorBlock;
3255
3256static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3257 CXClientData client_data) {
3258 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3259 return block->invoke(block, cursor, parent);
3260}
3261#endif
3262
3263
3264unsigned clang_visitChildrenWithBlock(CXCursor parent,
3265 CXCursorVisitorBlock block) {
3266 return clang_visitChildren(parent, visitWithBlock, block);
3267}
3268
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003269static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003270 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003271 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003272
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003273 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003274 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003275 if (const ObjCPropertyImplDecl *PropImpl =
3276 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003277 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003278 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003279
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003280 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003281 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003282 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003283
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003284 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003285 }
3286
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003287 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003288 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003289
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003290 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003291 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3292 // and returns different names. NamedDecl returns the class name and
3293 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003294 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003295
3296 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003297 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003298
3299 SmallString<1024> S;
3300 llvm::raw_svector_ostream os(S);
3301 ND->printName(os);
3302
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003303 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003304}
3305
3306CXString clang_getCursorSpelling(CXCursor C) {
3307 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003308 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003309
3310 if (clang_isReference(C.kind)) {
3311 switch (C.kind) {
3312 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003313 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003314 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003315 }
3316 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003317 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003318 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003319 }
3320 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003321 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003322 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003323 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003324 }
3325 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003326 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003327 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003328 }
3329 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003330 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003331 assert(Type && "Missing type decl");
3332
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003333 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 getAsString());
3335 }
3336 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003337 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 assert(Template && "Missing template decl");
3339
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003340 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003341 }
3342
3343 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003344 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003345 assert(NS && "Missing namespace decl");
3346
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003347 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 }
3349
3350 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003351 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003352 assert(Field && "Missing member decl");
3353
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003354 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003355 }
3356
3357 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003358 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003359 assert(Label && "Missing label");
3360
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003361 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003362 }
3363
3364 case CXCursor_OverloadedDeclRef: {
3365 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003366 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3367 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003368 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003369 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003370 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003371 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003372 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 OverloadedTemplateStorage *Ovl
3374 = Storage.get<OverloadedTemplateStorage*>();
3375 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003376 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003377 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 }
3379
3380 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003381 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003382 assert(Var && "Missing variable decl");
3383
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003384 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003385 }
3386
3387 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003388 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003389 }
3390 }
3391
3392 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003393 const Expr *E = getCursorExpr(C);
3394
3395 if (C.kind == CXCursor_ObjCStringLiteral ||
3396 C.kind == CXCursor_StringLiteral) {
3397 const StringLiteral *SLit;
3398 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3399 SLit = OSL->getString();
3400 } else {
3401 SLit = cast<StringLiteral>(E);
3402 }
3403 SmallString<256> Buf;
3404 llvm::raw_svector_ostream OS(Buf);
3405 SLit->outputString(OS);
3406 return cxstring::createDup(OS.str());
3407 }
3408
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003409 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003410 if (D)
3411 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003412 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003413 }
3414
3415 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003416 const Stmt *S = getCursorStmt(C);
3417 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003418 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003419
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003420 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003421 }
3422
3423 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003424 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003425 ->getNameStart());
3426
3427 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003428 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003429 ->getNameStart());
3430
3431 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003432 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003433
3434 if (clang_isDeclaration(C.kind))
3435 return getDeclSpelling(getCursorDecl(C));
3436
3437 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003438 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003439 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003440 }
3441
3442 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003443 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003444 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003445 }
3446
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003447 if (C.kind == CXCursor_PackedAttr) {
3448 return cxstring::createRef("packed");
3449 }
3450
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003451 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003452}
3453
3454CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3455 unsigned pieceIndex,
3456 unsigned options) {
3457 if (clang_Cursor_isNull(C))
3458 return clang_getNullRange();
3459
3460 ASTContext &Ctx = getCursorContext(C);
3461
3462 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003463 const Stmt *S = getCursorStmt(C);
3464 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003465 if (pieceIndex > 0)
3466 return clang_getNullRange();
3467 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3468 }
3469
3470 return clang_getNullRange();
3471 }
3472
3473 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003474 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003475 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3476 if (pieceIndex >= ME->getNumSelectorLocs())
3477 return clang_getNullRange();
3478 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3479 }
3480 }
3481
3482 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3483 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003484 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003485 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3486 if (pieceIndex >= MD->getNumSelectorLocs())
3487 return clang_getNullRange();
3488 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3489 }
3490 }
3491
3492 if (C.kind == CXCursor_ObjCCategoryDecl ||
3493 C.kind == CXCursor_ObjCCategoryImplDecl) {
3494 if (pieceIndex > 0)
3495 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003496 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003497 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3498 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003499 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003500 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3501 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3502 }
3503
3504 if (C.kind == CXCursor_ModuleImportDecl) {
3505 if (pieceIndex > 0)
3506 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003507 if (const ImportDecl *ImportD =
3508 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003509 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3510 if (!Locs.empty())
3511 return cxloc::translateSourceRange(Ctx,
3512 SourceRange(Locs.front(), Locs.back()));
3513 }
3514 return clang_getNullRange();
3515 }
3516
3517 // FIXME: A CXCursor_InclusionDirective should give the location of the
3518 // filename, but we don't keep track of this.
3519
3520 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3521 // but we don't keep track of this.
3522
3523 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3524 // but we don't keep track of this.
3525
3526 // Default handling, give the location of the cursor.
3527
3528 if (pieceIndex > 0)
3529 return clang_getNullRange();
3530
3531 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3532 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3533 return cxloc::translateSourceRange(Ctx, Loc);
3534}
3535
3536CXString clang_getCursorDisplayName(CXCursor C) {
3537 if (!clang_isDeclaration(C.kind))
3538 return clang_getCursorSpelling(C);
3539
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003540 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003541 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003542 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003543
3544 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003545 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003546 D = FunTmpl->getTemplatedDecl();
3547
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003548 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 SmallString<64> Str;
3550 llvm::raw_svector_ostream OS(Str);
3551 OS << *Function;
3552 if (Function->getPrimaryTemplate())
3553 OS << "<>";
3554 OS << "(";
3555 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3556 if (I)
3557 OS << ", ";
3558 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3559 }
3560
3561 if (Function->isVariadic()) {
3562 if (Function->getNumParams())
3563 OS << ", ";
3564 OS << "...";
3565 }
3566 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003567 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003568 }
3569
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003570 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 SmallString<64> Str;
3572 llvm::raw_svector_ostream OS(Str);
3573 OS << *ClassTemplate;
3574 OS << "<";
3575 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3576 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3577 if (I)
3578 OS << ", ";
3579
3580 NamedDecl *Param = Params->getParam(I);
3581 if (Param->getIdentifier()) {
3582 OS << Param->getIdentifier()->getName();
3583 continue;
3584 }
3585
3586 // There is no parameter name, which makes this tricky. Try to come up
3587 // with something useful that isn't too long.
3588 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3589 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3590 else if (NonTypeTemplateParmDecl *NTTP
3591 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3592 OS << NTTP->getType().getAsString(Policy);
3593 else
3594 OS << "template<...> class";
3595 }
3596
3597 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003598 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 }
3600
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003601 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003602 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3603 // If the type was explicitly written, use that.
3604 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003605 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003606
Benjamin Kramer9170e912013-02-22 15:46:01 +00003607 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003608 llvm::raw_svector_ostream OS(Str);
3609 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003610 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003611 ClassSpec->getTemplateArgs().data(),
3612 ClassSpec->getTemplateArgs().size(),
3613 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003614 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003615 }
3616
3617 return clang_getCursorSpelling(C);
3618}
3619
3620CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3621 switch (Kind) {
3622 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003623 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003624 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003625 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003626 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003627 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003628 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003629 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003630 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003631 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003632 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003633 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003635 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003637 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003641 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003643 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003645 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003647 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003651 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003653 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003655 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003659 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003663 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003665 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003673 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003750 case CXCursor_ObjCSelfExpr:
3751 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003868 case CXCursor_PackedAttr:
3869 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003870 case CXCursor_PureAttr:
3871 return cxstring::createRef("attribute(pure)");
3872 case CXCursor_ConstAttr:
3873 return cxstring::createRef("attribute(const)");
3874 case CXCursor_NoDuplicateAttr:
3875 return cxstring::createRef("attribute(noduplicate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003924 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003925 return cxstring::createRef("OMPParallelDirective");
3926 case CXCursor_OMPSimdDirective:
3927 return cxstring::createRef("OMPSimdDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 }
3929
3930 llvm_unreachable("Unhandled CXCursorKind");
3931}
3932
3933struct GetCursorData {
3934 SourceLocation TokenBeginLoc;
3935 bool PointsAtMacroArgExpansion;
3936 bool VisitedObjCPropertyImplDecl;
3937 SourceLocation VisitedDeclaratorDeclStartLoc;
3938 CXCursor &BestCursor;
3939
3940 GetCursorData(SourceManager &SM,
3941 SourceLocation tokenBegin, CXCursor &outputCursor)
3942 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3943 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3944 VisitedObjCPropertyImplDecl = false;
3945 }
3946};
3947
3948static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3949 CXCursor parent,
3950 CXClientData client_data) {
3951 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3952 CXCursor *BestCursor = &Data->BestCursor;
3953
3954 // If we point inside a macro argument we should provide info of what the
3955 // token is so use the actual cursor, don't replace it with a macro expansion
3956 // cursor.
3957 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3958 return CXChildVisit_Recurse;
3959
3960 if (clang_isDeclaration(cursor.kind)) {
3961 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003962 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003963 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3964 if (MD->isImplicit())
3965 return CXChildVisit_Break;
3966
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003967 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003968 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3969 // Check that when we have multiple @class references in the same line,
3970 // that later ones do not override the previous ones.
3971 // If we have:
3972 // @class Foo, Bar;
3973 // source ranges for both start at '@', so 'Bar' will end up overriding
3974 // 'Foo' even though the cursor location was at 'Foo'.
3975 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3976 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003977 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003978 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3979 if (PrevID != ID &&
3980 !PrevID->isThisDeclarationADefinition() &&
3981 !ID->isThisDeclarationADefinition())
3982 return CXChildVisit_Break;
3983 }
3984
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003985 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3987 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3988 // Check that when we have multiple declarators in the same line,
3989 // that later ones do not override the previous ones.
3990 // If we have:
3991 // int Foo, Bar;
3992 // source ranges for both start at 'int', so 'Bar' will end up overriding
3993 // 'Foo' even though the cursor location was at 'Foo'.
3994 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3995 return CXChildVisit_Break;
3996 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3997
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003998 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003999 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4000 (void)PropImp;
4001 // Check that when we have multiple @synthesize in the same line,
4002 // that later ones do not override the previous ones.
4003 // If we have:
4004 // @synthesize Foo, Bar;
4005 // source ranges for both start at '@', so 'Bar' will end up overriding
4006 // 'Foo' even though the cursor location was at 'Foo'.
4007 if (Data->VisitedObjCPropertyImplDecl)
4008 return CXChildVisit_Break;
4009 Data->VisitedObjCPropertyImplDecl = true;
4010 }
4011 }
4012
4013 if (clang_isExpression(cursor.kind) &&
4014 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004015 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004016 // Avoid having the cursor of an expression replace the declaration cursor
4017 // when the expression source range overlaps the declaration range.
4018 // This can happen for C++ constructor expressions whose range generally
4019 // include the variable declaration, e.g.:
4020 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4021 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4022 D->getLocation() == Data->TokenBeginLoc)
4023 return CXChildVisit_Break;
4024 }
4025 }
4026
4027 // If our current best cursor is the construction of a temporary object,
4028 // don't replace that cursor with a type reference, because we want
4029 // clang_getCursor() to point at the constructor.
4030 if (clang_isExpression(BestCursor->kind) &&
4031 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4032 cursor.kind == CXCursor_TypeRef) {
4033 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4034 // as having the actual point on the type reference.
4035 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4036 return CXChildVisit_Recurse;
4037 }
4038
4039 *BestCursor = cursor;
4040 return CXChildVisit_Recurse;
4041}
4042
4043CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004044 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004045 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004046 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004047 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004048
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004049 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4051
4052 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4053 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4054
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004055 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004056 CXFile SearchFile;
4057 unsigned SearchLine, SearchColumn;
4058 CXFile ResultFile;
4059 unsigned ResultLine, ResultColumn;
4060 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4061 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4062 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4063
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004064 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4065 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004066 &ResultColumn, 0);
4067 SearchFileName = clang_getFileName(SearchFile);
4068 ResultFileName = clang_getFileName(ResultFile);
4069 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4070 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004071 *Log << llvm::format("(%s:%d:%d) = %s",
4072 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4073 clang_getCString(KindSpelling))
4074 << llvm::format("(%s:%d:%d):%s%s",
4075 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4076 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004077 clang_disposeString(SearchFileName);
4078 clang_disposeString(ResultFileName);
4079 clang_disposeString(KindSpelling);
4080 clang_disposeString(USR);
4081
4082 CXCursor Definition = clang_getCursorDefinition(Result);
4083 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4084 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4085 CXString DefinitionKindSpelling
4086 = clang_getCursorKindSpelling(Definition.kind);
4087 CXFile DefinitionFile;
4088 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004089 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 &DefinitionLine, &DefinitionColumn, 0);
4091 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004092 *Log << llvm::format(" -> %s(%s:%d:%d)",
4093 clang_getCString(DefinitionKindSpelling),
4094 clang_getCString(DefinitionFileName),
4095 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004096 clang_disposeString(DefinitionFileName);
4097 clang_disposeString(DefinitionKindSpelling);
4098 }
4099 }
4100
4101 return Result;
4102}
4103
4104CXCursor clang_getNullCursor(void) {
4105 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4106}
4107
4108unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004109 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4110 // can't set consistently. For example, when visiting a DeclStmt we will set
4111 // it but we don't set it on the result of clang_getCursorDefinition for
4112 // a reference of the same declaration.
4113 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4114 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4115 // to provide that kind of info.
4116 if (clang_isDeclaration(X.kind))
4117 X.data[1] = 0;
4118 if (clang_isDeclaration(Y.kind))
4119 Y.data[1] = 0;
4120
Guy Benyei11169dd2012-12-18 14:30:41 +00004121 return X == Y;
4122}
4123
4124unsigned clang_hashCursor(CXCursor C) {
4125 unsigned Index = 0;
4126 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4127 Index = 1;
4128
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004129 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004130 std::make_pair(C.kind, C.data[Index]));
4131}
4132
4133unsigned clang_isInvalid(enum CXCursorKind K) {
4134 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4135}
4136
4137unsigned clang_isDeclaration(enum CXCursorKind K) {
4138 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4139 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4140}
4141
4142unsigned clang_isReference(enum CXCursorKind K) {
4143 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4144}
4145
4146unsigned clang_isExpression(enum CXCursorKind K) {
4147 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4148}
4149
4150unsigned clang_isStatement(enum CXCursorKind K) {
4151 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4152}
4153
4154unsigned clang_isAttribute(enum CXCursorKind K) {
4155 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4156}
4157
4158unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4159 return K == CXCursor_TranslationUnit;
4160}
4161
4162unsigned clang_isPreprocessing(enum CXCursorKind K) {
4163 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4164}
4165
4166unsigned clang_isUnexposed(enum CXCursorKind K) {
4167 switch (K) {
4168 case CXCursor_UnexposedDecl:
4169 case CXCursor_UnexposedExpr:
4170 case CXCursor_UnexposedStmt:
4171 case CXCursor_UnexposedAttr:
4172 return true;
4173 default:
4174 return false;
4175 }
4176}
4177
4178CXCursorKind clang_getCursorKind(CXCursor C) {
4179 return C.kind;
4180}
4181
4182CXSourceLocation clang_getCursorLocation(CXCursor C) {
4183 if (clang_isReference(C.kind)) {
4184 switch (C.kind) {
4185 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004186 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 = getCursorObjCSuperClassRef(C);
4188 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4189 }
4190
4191 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004192 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 = getCursorObjCProtocolRef(C);
4194 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4195 }
4196
4197 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004198 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 = getCursorObjCClassRef(C);
4200 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4201 }
4202
4203 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004204 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4206 }
4207
4208 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004209 std::pair<const TemplateDecl *, SourceLocation> P =
4210 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4212 }
4213
4214 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004215 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004216 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4217 }
4218
4219 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004220 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004221 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4222 }
4223
4224 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004225 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004226 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4227 }
4228
4229 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004230 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004231 if (!BaseSpec)
4232 return clang_getNullLocation();
4233
4234 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4235 return cxloc::translateSourceLocation(getCursorContext(C),
4236 TSInfo->getTypeLoc().getBeginLoc());
4237
4238 return cxloc::translateSourceLocation(getCursorContext(C),
4239 BaseSpec->getLocStart());
4240 }
4241
4242 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004243 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004244 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4245 }
4246
4247 case CXCursor_OverloadedDeclRef:
4248 return cxloc::translateSourceLocation(getCursorContext(C),
4249 getCursorOverloadedDeclRef(C).second);
4250
4251 default:
4252 // FIXME: Need a way to enumerate all non-reference cases.
4253 llvm_unreachable("Missed a reference kind");
4254 }
4255 }
4256
4257 if (clang_isExpression(C.kind))
4258 return cxloc::translateSourceLocation(getCursorContext(C),
4259 getLocationFromExpr(getCursorExpr(C)));
4260
4261 if (clang_isStatement(C.kind))
4262 return cxloc::translateSourceLocation(getCursorContext(C),
4263 getCursorStmt(C)->getLocStart());
4264
4265 if (C.kind == CXCursor_PreprocessingDirective) {
4266 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4267 return cxloc::translateSourceLocation(getCursorContext(C), L);
4268 }
4269
4270 if (C.kind == CXCursor_MacroExpansion) {
4271 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004272 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004273 return cxloc::translateSourceLocation(getCursorContext(C), L);
4274 }
4275
4276 if (C.kind == CXCursor_MacroDefinition) {
4277 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4278 return cxloc::translateSourceLocation(getCursorContext(C), L);
4279 }
4280
4281 if (C.kind == CXCursor_InclusionDirective) {
4282 SourceLocation L
4283 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4284 return cxloc::translateSourceLocation(getCursorContext(C), L);
4285 }
4286
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004287 if (clang_isAttribute(C.kind)) {
4288 SourceLocation L
4289 = cxcursor::getCursorAttr(C)->getLocation();
4290 return cxloc::translateSourceLocation(getCursorContext(C), L);
4291 }
4292
Guy Benyei11169dd2012-12-18 14:30:41 +00004293 if (!clang_isDeclaration(C.kind))
4294 return clang_getNullLocation();
4295
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004296 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004297 if (!D)
4298 return clang_getNullLocation();
4299
4300 SourceLocation Loc = D->getLocation();
4301 // FIXME: Multiple variables declared in a single declaration
4302 // currently lack the information needed to correctly determine their
4303 // ranges when accounting for the type-specifier. We use context
4304 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4305 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004306 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004307 if (!cxcursor::isFirstInDeclGroup(C))
4308 Loc = VD->getLocation();
4309 }
4310
4311 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004312 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004313 Loc = MD->getSelectorStartLoc();
4314
4315 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4316}
4317
4318} // end extern "C"
4319
4320CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4321 assert(TU);
4322
4323 // Guard against an invalid SourceLocation, or we may assert in one
4324 // of the following calls.
4325 if (SLoc.isInvalid())
4326 return clang_getNullCursor();
4327
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004328 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004329
4330 // Translate the given source location to make it point at the beginning of
4331 // the token under the cursor.
4332 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4333 CXXUnit->getASTContext().getLangOpts());
4334
4335 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4336 if (SLoc.isValid()) {
4337 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4338 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4339 /*VisitPreprocessorLast=*/true,
4340 /*VisitIncludedEntities=*/false,
4341 SourceLocation(SLoc));
4342 CursorVis.visitFileRegion();
4343 }
4344
4345 return Result;
4346}
4347
4348static SourceRange getRawCursorExtent(CXCursor C) {
4349 if (clang_isReference(C.kind)) {
4350 switch (C.kind) {
4351 case CXCursor_ObjCSuperClassRef:
4352 return getCursorObjCSuperClassRef(C).second;
4353
4354 case CXCursor_ObjCProtocolRef:
4355 return getCursorObjCProtocolRef(C).second;
4356
4357 case CXCursor_ObjCClassRef:
4358 return getCursorObjCClassRef(C).second;
4359
4360 case CXCursor_TypeRef:
4361 return getCursorTypeRef(C).second;
4362
4363 case CXCursor_TemplateRef:
4364 return getCursorTemplateRef(C).second;
4365
4366 case CXCursor_NamespaceRef:
4367 return getCursorNamespaceRef(C).second;
4368
4369 case CXCursor_MemberRef:
4370 return getCursorMemberRef(C).second;
4371
4372 case CXCursor_CXXBaseSpecifier:
4373 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4374
4375 case CXCursor_LabelRef:
4376 return getCursorLabelRef(C).second;
4377
4378 case CXCursor_OverloadedDeclRef:
4379 return getCursorOverloadedDeclRef(C).second;
4380
4381 case CXCursor_VariableRef:
4382 return getCursorVariableRef(C).second;
4383
4384 default:
4385 // FIXME: Need a way to enumerate all non-reference cases.
4386 llvm_unreachable("Missed a reference kind");
4387 }
4388 }
4389
4390 if (clang_isExpression(C.kind))
4391 return getCursorExpr(C)->getSourceRange();
4392
4393 if (clang_isStatement(C.kind))
4394 return getCursorStmt(C)->getSourceRange();
4395
4396 if (clang_isAttribute(C.kind))
4397 return getCursorAttr(C)->getRange();
4398
4399 if (C.kind == CXCursor_PreprocessingDirective)
4400 return cxcursor::getCursorPreprocessingDirective(C);
4401
4402 if (C.kind == CXCursor_MacroExpansion) {
4403 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004404 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004405 return TU->mapRangeFromPreamble(Range);
4406 }
4407
4408 if (C.kind == CXCursor_MacroDefinition) {
4409 ASTUnit *TU = getCursorASTUnit(C);
4410 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4411 return TU->mapRangeFromPreamble(Range);
4412 }
4413
4414 if (C.kind == CXCursor_InclusionDirective) {
4415 ASTUnit *TU = getCursorASTUnit(C);
4416 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4417 return TU->mapRangeFromPreamble(Range);
4418 }
4419
4420 if (C.kind == CXCursor_TranslationUnit) {
4421 ASTUnit *TU = getCursorASTUnit(C);
4422 FileID MainID = TU->getSourceManager().getMainFileID();
4423 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4424 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4425 return SourceRange(Start, End);
4426 }
4427
4428 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004429 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004430 if (!D)
4431 return SourceRange();
4432
4433 SourceRange R = D->getSourceRange();
4434 // FIXME: Multiple variables declared in a single declaration
4435 // currently lack the information needed to correctly determine their
4436 // ranges when accounting for the type-specifier. We use context
4437 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4438 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004439 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004440 if (!cxcursor::isFirstInDeclGroup(C))
4441 R.setBegin(VD->getLocation());
4442 }
4443 return R;
4444 }
4445 return SourceRange();
4446}
4447
4448/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4449/// the decl-specifier-seq for declarations.
4450static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4451 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004452 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004453 if (!D)
4454 return SourceRange();
4455
4456 SourceRange R = D->getSourceRange();
4457
4458 // Adjust the start of the location for declarations preceded by
4459 // declaration specifiers.
4460 SourceLocation StartLoc;
4461 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4462 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4463 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004464 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004465 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4466 StartLoc = TI->getTypeLoc().getLocStart();
4467 }
4468
4469 if (StartLoc.isValid() && R.getBegin().isValid() &&
4470 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4471 R.setBegin(StartLoc);
4472
4473 // FIXME: Multiple variables declared in a single declaration
4474 // currently lack the information needed to correctly determine their
4475 // ranges when accounting for the type-specifier. We use context
4476 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4477 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004478 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004479 if (!cxcursor::isFirstInDeclGroup(C))
4480 R.setBegin(VD->getLocation());
4481 }
4482
4483 return R;
4484 }
4485
4486 return getRawCursorExtent(C);
4487}
4488
4489extern "C" {
4490
4491CXSourceRange clang_getCursorExtent(CXCursor C) {
4492 SourceRange R = getRawCursorExtent(C);
4493 if (R.isInvalid())
4494 return clang_getNullRange();
4495
4496 return cxloc::translateSourceRange(getCursorContext(C), R);
4497}
4498
4499CXCursor clang_getCursorReferenced(CXCursor C) {
4500 if (clang_isInvalid(C.kind))
4501 return clang_getNullCursor();
4502
4503 CXTranslationUnit tu = getCursorTU(C);
4504 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004505 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004506 if (!D)
4507 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004508 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004509 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004510 if (const ObjCPropertyImplDecl *PropImpl =
4511 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004512 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4513 return MakeCXCursor(Property, tu);
4514
4515 return C;
4516 }
4517
4518 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004519 const Expr *E = getCursorExpr(C);
4520 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004521 if (D) {
4522 CXCursor declCursor = MakeCXCursor(D, tu);
4523 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4524 declCursor);
4525 return declCursor;
4526 }
4527
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004528 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004529 return MakeCursorOverloadedDeclRef(Ovl, tu);
4530
4531 return clang_getNullCursor();
4532 }
4533
4534 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004535 const Stmt *S = getCursorStmt(C);
4536 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004537 if (LabelDecl *label = Goto->getLabel())
4538 if (LabelStmt *labelS = label->getStmt())
4539 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4540
4541 return clang_getNullCursor();
4542 }
4543
4544 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004545 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004546 return MakeMacroDefinitionCursor(Def, tu);
4547 }
4548
4549 if (!clang_isReference(C.kind))
4550 return clang_getNullCursor();
4551
4552 switch (C.kind) {
4553 case CXCursor_ObjCSuperClassRef:
4554 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4555
4556 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004557 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4558 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004559 return MakeCXCursor(Def, tu);
4560
4561 return MakeCXCursor(Prot, tu);
4562 }
4563
4564 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004565 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4566 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004567 return MakeCXCursor(Def, tu);
4568
4569 return MakeCXCursor(Class, tu);
4570 }
4571
4572 case CXCursor_TypeRef:
4573 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4574
4575 case CXCursor_TemplateRef:
4576 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4577
4578 case CXCursor_NamespaceRef:
4579 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4580
4581 case CXCursor_MemberRef:
4582 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4583
4584 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004585 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004586 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4587 tu ));
4588 }
4589
4590 case CXCursor_LabelRef:
4591 // FIXME: We end up faking the "parent" declaration here because we
4592 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004593 return MakeCXCursor(getCursorLabelRef(C).first,
4594 cxtu::getASTUnit(tu)->getASTContext()
4595 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004596 tu);
4597
4598 case CXCursor_OverloadedDeclRef:
4599 return C;
4600
4601 case CXCursor_VariableRef:
4602 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4603
4604 default:
4605 // We would prefer to enumerate all non-reference cursor kinds here.
4606 llvm_unreachable("Unhandled reference cursor kind");
4607 }
4608}
4609
4610CXCursor clang_getCursorDefinition(CXCursor C) {
4611 if (clang_isInvalid(C.kind))
4612 return clang_getNullCursor();
4613
4614 CXTranslationUnit TU = getCursorTU(C);
4615
4616 bool WasReference = false;
4617 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4618 C = clang_getCursorReferenced(C);
4619 WasReference = true;
4620 }
4621
4622 if (C.kind == CXCursor_MacroExpansion)
4623 return clang_getCursorReferenced(C);
4624
4625 if (!clang_isDeclaration(C.kind))
4626 return clang_getNullCursor();
4627
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004628 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004629 if (!D)
4630 return clang_getNullCursor();
4631
4632 switch (D->getKind()) {
4633 // Declaration kinds that don't really separate the notions of
4634 // declaration and definition.
4635 case Decl::Namespace:
4636 case Decl::Typedef:
4637 case Decl::TypeAlias:
4638 case Decl::TypeAliasTemplate:
4639 case Decl::TemplateTypeParm:
4640 case Decl::EnumConstant:
4641 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004642 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004643 case Decl::IndirectField:
4644 case Decl::ObjCIvar:
4645 case Decl::ObjCAtDefsField:
4646 case Decl::ImplicitParam:
4647 case Decl::ParmVar:
4648 case Decl::NonTypeTemplateParm:
4649 case Decl::TemplateTemplateParm:
4650 case Decl::ObjCCategoryImpl:
4651 case Decl::ObjCImplementation:
4652 case Decl::AccessSpec:
4653 case Decl::LinkageSpec:
4654 case Decl::ObjCPropertyImpl:
4655 case Decl::FileScopeAsm:
4656 case Decl::StaticAssert:
4657 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004658 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004659 case Decl::Label: // FIXME: Is this right??
4660 case Decl::ClassScopeFunctionSpecialization:
4661 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004662 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004663 return C;
4664
4665 // Declaration kinds that don't make any sense here, but are
4666 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004667 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004668 case Decl::TranslationUnit:
4669 break;
4670
4671 // Declaration kinds for which the definition is not resolvable.
4672 case Decl::UnresolvedUsingTypename:
4673 case Decl::UnresolvedUsingValue:
4674 break;
4675
4676 case Decl::UsingDirective:
4677 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4678 TU);
4679
4680 case Decl::NamespaceAlias:
4681 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4682
4683 case Decl::Enum:
4684 case Decl::Record:
4685 case Decl::CXXRecord:
4686 case Decl::ClassTemplateSpecialization:
4687 case Decl::ClassTemplatePartialSpecialization:
4688 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4689 return MakeCXCursor(Def, TU);
4690 return clang_getNullCursor();
4691
4692 case Decl::Function:
4693 case Decl::CXXMethod:
4694 case Decl::CXXConstructor:
4695 case Decl::CXXDestructor:
4696 case Decl::CXXConversion: {
4697 const FunctionDecl *Def = 0;
4698 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004699 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004700 return clang_getNullCursor();
4701 }
4702
Larisse Voufo39a1e502013-08-06 01:03:05 +00004703 case Decl::Var:
4704 case Decl::VarTemplateSpecialization:
4705 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004706 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004707 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004708 return MakeCXCursor(Def, TU);
4709 return clang_getNullCursor();
4710 }
4711
4712 case Decl::FunctionTemplate: {
4713 const FunctionDecl *Def = 0;
4714 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4715 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4716 return clang_getNullCursor();
4717 }
4718
4719 case Decl::ClassTemplate: {
4720 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4721 ->getDefinition())
4722 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4723 TU);
4724 return clang_getNullCursor();
4725 }
4726
Larisse Voufo39a1e502013-08-06 01:03:05 +00004727 case Decl::VarTemplate: {
4728 if (VarDecl *Def =
4729 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4730 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4731 return clang_getNullCursor();
4732 }
4733
Guy Benyei11169dd2012-12-18 14:30:41 +00004734 case Decl::Using:
4735 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4736 D->getLocation(), TU);
4737
4738 case Decl::UsingShadow:
4739 return clang_getCursorDefinition(
4740 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4741 TU));
4742
4743 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004744 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004745 if (Method->isThisDeclarationADefinition())
4746 return C;
4747
4748 // Dig out the method definition in the associated
4749 // @implementation, if we have it.
4750 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004751 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004752 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4753 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4754 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4755 Method->isInstanceMethod()))
4756 if (Def->isThisDeclarationADefinition())
4757 return MakeCXCursor(Def, TU);
4758
4759 return clang_getNullCursor();
4760 }
4761
4762 case Decl::ObjCCategory:
4763 if (ObjCCategoryImplDecl *Impl
4764 = cast<ObjCCategoryDecl>(D)->getImplementation())
4765 return MakeCXCursor(Impl, TU);
4766 return clang_getNullCursor();
4767
4768 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004769 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004770 return MakeCXCursor(Def, TU);
4771 return clang_getNullCursor();
4772
4773 case Decl::ObjCInterface: {
4774 // There are two notions of a "definition" for an Objective-C
4775 // class: the interface and its implementation. When we resolved a
4776 // reference to an Objective-C class, produce the @interface as
4777 // the definition; when we were provided with the interface,
4778 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004779 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004780 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004781 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004782 return MakeCXCursor(Def, TU);
4783 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4784 return MakeCXCursor(Impl, TU);
4785 return clang_getNullCursor();
4786 }
4787
4788 case Decl::ObjCProperty:
4789 // FIXME: We don't really know where to find the
4790 // ObjCPropertyImplDecls that implement this property.
4791 return clang_getNullCursor();
4792
4793 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004794 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004795 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004796 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004797 return MakeCXCursor(Def, TU);
4798
4799 return clang_getNullCursor();
4800
4801 case Decl::Friend:
4802 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4803 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4804 return clang_getNullCursor();
4805
4806 case Decl::FriendTemplate:
4807 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4808 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4809 return clang_getNullCursor();
4810 }
4811
4812 return clang_getNullCursor();
4813}
4814
4815unsigned clang_isCursorDefinition(CXCursor C) {
4816 if (!clang_isDeclaration(C.kind))
4817 return 0;
4818
4819 return clang_getCursorDefinition(C) == C;
4820}
4821
4822CXCursor clang_getCanonicalCursor(CXCursor C) {
4823 if (!clang_isDeclaration(C.kind))
4824 return C;
4825
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004826 if (const Decl *D = getCursorDecl(C)) {
4827 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004828 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4829 return MakeCXCursor(CatD, getCursorTU(C));
4830
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004831 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4832 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004833 return MakeCXCursor(IFD, getCursorTU(C));
4834
4835 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4836 }
4837
4838 return C;
4839}
4840
4841int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4842 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4843}
4844
4845unsigned clang_getNumOverloadedDecls(CXCursor C) {
4846 if (C.kind != CXCursor_OverloadedDeclRef)
4847 return 0;
4848
4849 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004850 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004851 return E->getNumDecls();
4852
4853 if (OverloadedTemplateStorage *S
4854 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4855 return S->size();
4856
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004857 const Decl *D = Storage.get<const Decl *>();
4858 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004859 return Using->shadow_size();
4860
4861 return 0;
4862}
4863
4864CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4865 if (cursor.kind != CXCursor_OverloadedDeclRef)
4866 return clang_getNullCursor();
4867
4868 if (index >= clang_getNumOverloadedDecls(cursor))
4869 return clang_getNullCursor();
4870
4871 CXTranslationUnit TU = getCursorTU(cursor);
4872 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004873 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004874 return MakeCXCursor(E->decls_begin()[index], TU);
4875
4876 if (OverloadedTemplateStorage *S
4877 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4878 return MakeCXCursor(S->begin()[index], TU);
4879
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004880 const Decl *D = Storage.get<const Decl *>();
4881 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004882 // FIXME: This is, unfortunately, linear time.
4883 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4884 std::advance(Pos, index);
4885 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4886 }
4887
4888 return clang_getNullCursor();
4889}
4890
4891void clang_getDefinitionSpellingAndExtent(CXCursor C,
4892 const char **startBuf,
4893 const char **endBuf,
4894 unsigned *startLine,
4895 unsigned *startColumn,
4896 unsigned *endLine,
4897 unsigned *endColumn) {
4898 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004899 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004900 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4901
4902 SourceManager &SM = FD->getASTContext().getSourceManager();
4903 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4904 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4905 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4906 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4907 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4908 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4909}
4910
4911
4912CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4913 unsigned PieceIndex) {
4914 RefNamePieces Pieces;
4915
4916 switch (C.kind) {
4917 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004918 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004919 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4920 E->getQualifierLoc().getSourceRange());
4921 break;
4922
4923 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004924 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004925 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4926 E->getQualifierLoc().getSourceRange(),
4927 E->getOptionalExplicitTemplateArgs());
4928 break;
4929
4930 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004931 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004932 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004933 const Expr *Callee = OCE->getCallee();
4934 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004935 Callee = ICE->getSubExpr();
4936
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004937 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004938 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4939 DRE->getQualifierLoc().getSourceRange());
4940 }
4941 break;
4942
4943 default:
4944 break;
4945 }
4946
4947 if (Pieces.empty()) {
4948 if (PieceIndex == 0)
4949 return clang_getCursorExtent(C);
4950 } else if (PieceIndex < Pieces.size()) {
4951 SourceRange R = Pieces[PieceIndex];
4952 if (R.isValid())
4953 return cxloc::translateSourceRange(getCursorContext(C), R);
4954 }
4955
4956 return clang_getNullRange();
4957}
4958
4959void clang_enableStackTraces(void) {
4960 llvm::sys::PrintStackTraceOnErrorSignal();
4961}
4962
4963void clang_executeOnThread(void (*fn)(void*), void *user_data,
4964 unsigned stack_size) {
4965 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4966}
4967
4968} // end: extern "C"
4969
4970//===----------------------------------------------------------------------===//
4971// Token-based Operations.
4972//===----------------------------------------------------------------------===//
4973
4974/* CXToken layout:
4975 * int_data[0]: a CXTokenKind
4976 * int_data[1]: starting token location
4977 * int_data[2]: token length
4978 * int_data[3]: reserved
4979 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4980 * otherwise unused.
4981 */
4982extern "C" {
4983
4984CXTokenKind clang_getTokenKind(CXToken CXTok) {
4985 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4986}
4987
4988CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4989 switch (clang_getTokenKind(CXTok)) {
4990 case CXToken_Identifier:
4991 case CXToken_Keyword:
4992 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004993 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004994 ->getNameStart());
4995
4996 case CXToken_Literal: {
4997 // We have stashed the starting pointer in the ptr_data field. Use it.
4998 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004999 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005000 }
5001
5002 case CXToken_Punctuation:
5003 case CXToken_Comment:
5004 break;
5005 }
5006
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005007 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005008 LOG_BAD_TU(TU);
5009 return cxstring::createEmpty();
5010 }
5011
Guy Benyei11169dd2012-12-18 14:30:41 +00005012 // We have to find the starting buffer pointer the hard way, by
5013 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005014 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005015 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005016 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005017
5018 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5019 std::pair<FileID, unsigned> LocInfo
5020 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5021 bool Invalid = false;
5022 StringRef Buffer
5023 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5024 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005025 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005026
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005027 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005028}
5029
5030CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005031 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005032 LOG_BAD_TU(TU);
5033 return clang_getNullLocation();
5034 }
5035
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005036 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005037 if (!CXXUnit)
5038 return clang_getNullLocation();
5039
5040 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5041 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5042}
5043
5044CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005045 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005046 LOG_BAD_TU(TU);
5047 return clang_getNullRange();
5048 }
5049
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005050 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005051 if (!CXXUnit)
5052 return clang_getNullRange();
5053
5054 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5055 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5056}
5057
5058static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5059 SmallVectorImpl<CXToken> &CXTokens) {
5060 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5061 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005062 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005063 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005064 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005065
5066 // Cannot tokenize across files.
5067 if (BeginLocInfo.first != EndLocInfo.first)
5068 return;
5069
5070 // Create a lexer
5071 bool Invalid = false;
5072 StringRef Buffer
5073 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5074 if (Invalid)
5075 return;
5076
5077 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5078 CXXUnit->getASTContext().getLangOpts(),
5079 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5080 Lex.SetCommentRetentionState(true);
5081
5082 // Lex tokens until we hit the end of the range.
5083 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5084 Token Tok;
5085 bool previousWasAt = false;
5086 do {
5087 // Lex the next token
5088 Lex.LexFromRawLexer(Tok);
5089 if (Tok.is(tok::eof))
5090 break;
5091
5092 // Initialize the CXToken.
5093 CXToken CXTok;
5094
5095 // - Common fields
5096 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5097 CXTok.int_data[2] = Tok.getLength();
5098 CXTok.int_data[3] = 0;
5099
5100 // - Kind-specific fields
5101 if (Tok.isLiteral()) {
5102 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005103 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005104 } else if (Tok.is(tok::raw_identifier)) {
5105 // Lookup the identifier to determine whether we have a keyword.
5106 IdentifierInfo *II
5107 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5108
5109 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5110 CXTok.int_data[0] = CXToken_Keyword;
5111 }
5112 else {
5113 CXTok.int_data[0] = Tok.is(tok::identifier)
5114 ? CXToken_Identifier
5115 : CXToken_Keyword;
5116 }
5117 CXTok.ptr_data = II;
5118 } else if (Tok.is(tok::comment)) {
5119 CXTok.int_data[0] = CXToken_Comment;
5120 CXTok.ptr_data = 0;
5121 } else {
5122 CXTok.int_data[0] = CXToken_Punctuation;
5123 CXTok.ptr_data = 0;
5124 }
5125 CXTokens.push_back(CXTok);
5126 previousWasAt = Tok.is(tok::at);
5127 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5128}
5129
5130void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5131 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005132 LOG_FUNC_SECTION {
5133 *Log << TU << ' ' << Range;
5134 }
5135
Guy Benyei11169dd2012-12-18 14:30:41 +00005136 if (Tokens)
5137 *Tokens = 0;
5138 if (NumTokens)
5139 *NumTokens = 0;
5140
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005141 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005142 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005143 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005144 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005145
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005146 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005147 if (!CXXUnit || !Tokens || !NumTokens)
5148 return;
5149
5150 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5151
5152 SourceRange R = cxloc::translateCXSourceRange(Range);
5153 if (R.isInvalid())
5154 return;
5155
5156 SmallVector<CXToken, 32> CXTokens;
5157 getTokens(CXXUnit, R, CXTokens);
5158
5159 if (CXTokens.empty())
5160 return;
5161
5162 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5163 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5164 *NumTokens = CXTokens.size();
5165}
5166
5167void clang_disposeTokens(CXTranslationUnit TU,
5168 CXToken *Tokens, unsigned NumTokens) {
5169 free(Tokens);
5170}
5171
5172} // end: extern "C"
5173
5174//===----------------------------------------------------------------------===//
5175// Token annotation APIs.
5176//===----------------------------------------------------------------------===//
5177
Guy Benyei11169dd2012-12-18 14:30:41 +00005178static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5179 CXCursor parent,
5180 CXClientData client_data);
5181static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5182 CXClientData client_data);
5183
5184namespace {
5185class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005186 CXToken *Tokens;
5187 CXCursor *Cursors;
5188 unsigned NumTokens;
5189 unsigned TokIdx;
5190 unsigned PreprocessingTokIdx;
5191 CursorVisitor AnnotateVis;
5192 SourceManager &SrcMgr;
5193 bool HasContextSensitiveKeywords;
5194
5195 struct PostChildrenInfo {
5196 CXCursor Cursor;
5197 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005198 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005199 unsigned BeforeChildrenTokenIdx;
5200 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005201 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005202
5203 CXToken &getTok(unsigned Idx) {
5204 assert(Idx < NumTokens);
5205 return Tokens[Idx];
5206 }
5207 const CXToken &getTok(unsigned Idx) const {
5208 assert(Idx < NumTokens);
5209 return Tokens[Idx];
5210 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005211 bool MoreTokens() const { return TokIdx < NumTokens; }
5212 unsigned NextToken() const { return TokIdx; }
5213 void AdvanceToken() { ++TokIdx; }
5214 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005215 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 }
5217 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005218 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005219 }
5220 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005221 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005222 }
5223
5224 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005225 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005226 SourceRange);
5227
5228public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005229 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005230 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005231 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005232 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005233 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005234 AnnotateTokensVisitor, this,
5235 /*VisitPreprocessorLast=*/true,
5236 /*VisitIncludedEntities=*/false,
5237 RegionOfInterest,
5238 /*VisitDeclsOnly=*/false,
5239 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005240 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005241 HasContextSensitiveKeywords(false) { }
5242
5243 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5244 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5245 bool postVisitChildren(CXCursor cursor);
5246 void AnnotateTokens();
5247
5248 /// \brief Determine whether the annotator saw any cursors that have
5249 /// context-sensitive keywords.
5250 bool hasContextSensitiveKeywords() const {
5251 return HasContextSensitiveKeywords;
5252 }
5253
5254 ~AnnotateTokensWorker() {
5255 assert(PostChildrenInfos.empty());
5256 }
5257};
5258}
5259
5260void AnnotateTokensWorker::AnnotateTokens() {
5261 // Walk the AST within the region of interest, annotating tokens
5262 // along the way.
5263 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005264}
Guy Benyei11169dd2012-12-18 14:30:41 +00005265
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005266static inline void updateCursorAnnotation(CXCursor &Cursor,
5267 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005268 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005269 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005270 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005271}
5272
5273/// \brief It annotates and advances tokens with a cursor until the comparison
5274//// between the cursor location and the source range is the same as
5275/// \arg compResult.
5276///
5277/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5278/// Pass RangeOverlap to annotate tokens inside a range.
5279void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5280 RangeComparisonResult compResult,
5281 SourceRange range) {
5282 while (MoreTokens()) {
5283 const unsigned I = NextToken();
5284 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005285 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5286 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005287
5288 SourceLocation TokLoc = GetTokenLoc(I);
5289 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005290 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005291 AdvanceToken();
5292 continue;
5293 }
5294 break;
5295 }
5296}
5297
5298/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005299/// \returns true if it advanced beyond all macro tokens, false otherwise.
5300bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005301 CXCursor updateC,
5302 RangeComparisonResult compResult,
5303 SourceRange range) {
5304 assert(MoreTokens());
5305 assert(isFunctionMacroToken(NextToken()) &&
5306 "Should be called only for macro arg tokens");
5307
5308 // This works differently than annotateAndAdvanceTokens; because expanded
5309 // macro arguments can have arbitrary translation-unit source order, we do not
5310 // advance the token index one by one until a token fails the range test.
5311 // We only advance once past all of the macro arg tokens if all of them
5312 // pass the range test. If one of them fails we keep the token index pointing
5313 // at the start of the macro arg tokens so that the failing token will be
5314 // annotated by a subsequent annotation try.
5315
5316 bool atLeastOneCompFail = false;
5317
5318 unsigned I = NextToken();
5319 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5320 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5321 if (TokLoc.isFileID())
5322 continue; // not macro arg token, it's parens or comma.
5323 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5324 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5325 Cursors[I] = updateC;
5326 } else
5327 atLeastOneCompFail = true;
5328 }
5329
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005330 if (atLeastOneCompFail)
5331 return false;
5332
5333 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5334 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005335}
5336
5337enum CXChildVisitResult
5338AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005339 SourceRange cursorRange = getRawCursorExtent(cursor);
5340 if (cursorRange.isInvalid())
5341 return CXChildVisit_Recurse;
5342
5343 if (!HasContextSensitiveKeywords) {
5344 // Objective-C properties can have context-sensitive keywords.
5345 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005346 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005347 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5348 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5349 }
5350 // Objective-C methods can have context-sensitive keywords.
5351 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5352 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005353 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005354 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5355 if (Method->getObjCDeclQualifier())
5356 HasContextSensitiveKeywords = true;
5357 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005358 for (const auto *P : Method->params()) {
5359 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005360 HasContextSensitiveKeywords = true;
5361 break;
5362 }
5363 }
5364 }
5365 }
5366 }
5367 // C++ methods can have context-sensitive keywords.
5368 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005369 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005370 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5371 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5372 HasContextSensitiveKeywords = true;
5373 }
5374 }
5375 // C++ classes can have context-sensitive keywords.
5376 else if (cursor.kind == CXCursor_StructDecl ||
5377 cursor.kind == CXCursor_ClassDecl ||
5378 cursor.kind == CXCursor_ClassTemplate ||
5379 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005380 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005381 if (D->hasAttr<FinalAttr>())
5382 HasContextSensitiveKeywords = true;
5383 }
5384 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005385
5386 // Don't override a property annotation with its getter/setter method.
5387 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5388 parent.kind == CXCursor_ObjCPropertyDecl)
5389 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005390
5391 if (clang_isPreprocessing(cursor.kind)) {
5392 // Items in the preprocessing record are kept separate from items in
5393 // declarations, so we keep a separate token index.
5394 unsigned SavedTokIdx = TokIdx;
5395 TokIdx = PreprocessingTokIdx;
5396
5397 // Skip tokens up until we catch up to the beginning of the preprocessing
5398 // entry.
5399 while (MoreTokens()) {
5400 const unsigned I = NextToken();
5401 SourceLocation TokLoc = GetTokenLoc(I);
5402 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5403 case RangeBefore:
5404 AdvanceToken();
5405 continue;
5406 case RangeAfter:
5407 case RangeOverlap:
5408 break;
5409 }
5410 break;
5411 }
5412
5413 // Look at all of the tokens within this range.
5414 while (MoreTokens()) {
5415 const unsigned I = NextToken();
5416 SourceLocation TokLoc = GetTokenLoc(I);
5417 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5418 case RangeBefore:
5419 llvm_unreachable("Infeasible");
5420 case RangeAfter:
5421 break;
5422 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005423 // For macro expansions, just note where the beginning of the macro
5424 // expansion occurs.
5425 if (cursor.kind == CXCursor_MacroExpansion) {
5426 if (TokLoc == cursorRange.getBegin())
5427 Cursors[I] = cursor;
5428 AdvanceToken();
5429 break;
5430 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005431 // We may have already annotated macro names inside macro definitions.
5432 if (Cursors[I].kind != CXCursor_MacroExpansion)
5433 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005434 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005435 continue;
5436 }
5437 break;
5438 }
5439
5440 // Save the preprocessing token index; restore the non-preprocessing
5441 // token index.
5442 PreprocessingTokIdx = TokIdx;
5443 TokIdx = SavedTokIdx;
5444 return CXChildVisit_Recurse;
5445 }
5446
5447 if (cursorRange.isInvalid())
5448 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005449
5450 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005451 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005452 const enum CXCursorKind K = clang_getCursorKind(parent);
5453 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005454 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5455 // Attributes are annotated out-of-order, skip tokens until we reach it.
5456 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005457 ? clang_getNullCursor() : parent;
5458
5459 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5460
5461 // Avoid having the cursor of an expression "overwrite" the annotation of the
5462 // variable declaration that it belongs to.
5463 // This can happen for C++ constructor expressions whose range generally
5464 // include the variable declaration, e.g.:
5465 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005466 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005467 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005468 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005469 const unsigned I = NextToken();
5470 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5471 E->getLocStart() == D->getLocation() &&
5472 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005473 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005474 AdvanceToken();
5475 }
5476 }
5477 }
5478
5479 // Before recursing into the children keep some state that we are going
5480 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5481 // extra work after the child nodes are visited.
5482 // Note that we don't call VisitChildren here to avoid traversing statements
5483 // code-recursively which can blow the stack.
5484
5485 PostChildrenInfo Info;
5486 Info.Cursor = cursor;
5487 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005488 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005489 Info.BeforeChildrenTokenIdx = NextToken();
5490 PostChildrenInfos.push_back(Info);
5491
5492 return CXChildVisit_Recurse;
5493}
5494
5495bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5496 if (PostChildrenInfos.empty())
5497 return false;
5498 const PostChildrenInfo &Info = PostChildrenInfos.back();
5499 if (!clang_equalCursors(Info.Cursor, cursor))
5500 return false;
5501
5502 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5503 const unsigned AfterChildren = NextToken();
5504 SourceRange cursorRange = Info.CursorRange;
5505
5506 // Scan the tokens that are at the end of the cursor, but are not captured
5507 // but the child cursors.
5508 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5509
5510 // Scan the tokens that are at the beginning of the cursor, but are not
5511 // capture by the child cursors.
5512 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5513 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5514 break;
5515
5516 Cursors[I] = cursor;
5517 }
5518
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005519 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5520 // encountered the attribute cursor.
5521 if (clang_isAttribute(cursor.kind))
5522 TokIdx = Info.BeforeReachingCursorIdx;
5523
Guy Benyei11169dd2012-12-18 14:30:41 +00005524 PostChildrenInfos.pop_back();
5525 return false;
5526}
5527
5528static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5529 CXCursor parent,
5530 CXClientData client_data) {
5531 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5532}
5533
5534static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5535 CXClientData client_data) {
5536 return static_cast<AnnotateTokensWorker*>(client_data)->
5537 postVisitChildren(cursor);
5538}
5539
5540namespace {
5541
5542/// \brief Uses the macro expansions in the preprocessing record to find
5543/// and mark tokens that are macro arguments. This info is used by the
5544/// AnnotateTokensWorker.
5545class MarkMacroArgTokensVisitor {
5546 SourceManager &SM;
5547 CXToken *Tokens;
5548 unsigned NumTokens;
5549 unsigned CurIdx;
5550
5551public:
5552 MarkMacroArgTokensVisitor(SourceManager &SM,
5553 CXToken *tokens, unsigned numTokens)
5554 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5555
5556 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5557 if (cursor.kind != CXCursor_MacroExpansion)
5558 return CXChildVisit_Continue;
5559
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005560 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005561 if (macroRange.getBegin() == macroRange.getEnd())
5562 return CXChildVisit_Continue; // it's not a function macro.
5563
5564 for (; CurIdx < NumTokens; ++CurIdx) {
5565 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5566 macroRange.getBegin()))
5567 break;
5568 }
5569
5570 if (CurIdx == NumTokens)
5571 return CXChildVisit_Break;
5572
5573 for (; CurIdx < NumTokens; ++CurIdx) {
5574 SourceLocation tokLoc = getTokenLoc(CurIdx);
5575 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5576 break;
5577
5578 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5579 }
5580
5581 if (CurIdx == NumTokens)
5582 return CXChildVisit_Break;
5583
5584 return CXChildVisit_Continue;
5585 }
5586
5587private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005588 CXToken &getTok(unsigned Idx) {
5589 assert(Idx < NumTokens);
5590 return Tokens[Idx];
5591 }
5592 const CXToken &getTok(unsigned Idx) const {
5593 assert(Idx < NumTokens);
5594 return Tokens[Idx];
5595 }
5596
Guy Benyei11169dd2012-12-18 14:30:41 +00005597 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005598 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005599 }
5600
5601 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5602 // The third field is reserved and currently not used. Use it here
5603 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005604 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005605 }
5606};
5607
5608} // end anonymous namespace
5609
5610static CXChildVisitResult
5611MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5612 CXClientData client_data) {
5613 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5614 parent);
5615}
5616
5617namespace {
5618 struct clang_annotateTokens_Data {
5619 CXTranslationUnit TU;
5620 ASTUnit *CXXUnit;
5621 CXToken *Tokens;
5622 unsigned NumTokens;
5623 CXCursor *Cursors;
5624 };
5625}
5626
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005627/// \brief Used by \c annotatePreprocessorTokens.
5628/// \returns true if lexing was finished, false otherwise.
5629static bool lexNext(Lexer &Lex, Token &Tok,
5630 unsigned &NextIdx, unsigned NumTokens) {
5631 if (NextIdx >= NumTokens)
5632 return true;
5633
5634 ++NextIdx;
5635 Lex.LexFromRawLexer(Tok);
5636 if (Tok.is(tok::eof))
5637 return true;
5638
5639 return false;
5640}
5641
Guy Benyei11169dd2012-12-18 14:30:41 +00005642static void annotatePreprocessorTokens(CXTranslationUnit TU,
5643 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005644 CXCursor *Cursors,
5645 CXToken *Tokens,
5646 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005647 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005648
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005649 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005650 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5651 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005652 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005653 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005654 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005655
5656 if (BeginLocInfo.first != EndLocInfo.first)
5657 return;
5658
5659 StringRef Buffer;
5660 bool Invalid = false;
5661 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5662 if (Buffer.empty() || Invalid)
5663 return;
5664
5665 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5666 CXXUnit->getASTContext().getLangOpts(),
5667 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5668 Buffer.end());
5669 Lex.SetCommentRetentionState(true);
5670
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005671 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005672 // Lex tokens in raw mode until we hit the end of the range, to avoid
5673 // entering #includes or expanding macros.
5674 while (true) {
5675 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005676 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5677 break;
5678 unsigned TokIdx = NextIdx-1;
5679 assert(Tok.getLocation() ==
5680 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005681
5682 reprocess:
5683 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005684 // We have found a preprocessing directive. Annotate the tokens
5685 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005686 //
5687 // FIXME: Some simple tests here could identify macro definitions and
5688 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005689
5690 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005691 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5692 break;
5693
5694 MacroInfo *MI = 0;
5695 if (Tok.is(tok::raw_identifier) &&
5696 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5697 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5698 break;
5699
5700 if (Tok.is(tok::raw_identifier)) {
5701 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5702 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5703 SourceLocation MappedTokLoc =
5704 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5705 MI = getMacroInfo(II, MappedTokLoc, TU);
5706 }
5707 }
5708
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005709 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005710 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005711 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5712 finished = true;
5713 break;
5714 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005715 // If we are in a macro definition, check if the token was ever a
5716 // macro name and annotate it if that's the case.
5717 if (MI) {
5718 SourceLocation SaveLoc = Tok.getLocation();
5719 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5720 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5721 Tok.setLocation(SaveLoc);
5722 if (MacroDef)
5723 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5724 Tok.getLocation(), TU);
5725 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005726 } while (!Tok.isAtStartOfLine());
5727
5728 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5729 assert(TokIdx <= LastIdx);
5730 SourceLocation EndLoc =
5731 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5732 CXCursor Cursor =
5733 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5734
5735 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005736 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005737
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005738 if (finished)
5739 break;
5740 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005741 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005742 }
5743}
5744
5745// This gets run a separate thread to avoid stack blowout.
5746static void clang_annotateTokensImpl(void *UserData) {
5747 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5748 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5749 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5750 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5751 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5752
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005753 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005754 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5755 setThreadBackgroundPriority();
5756
5757 // Determine the region of interest, which contains all of the tokens.
5758 SourceRange RegionOfInterest;
5759 RegionOfInterest.setBegin(
5760 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5761 RegionOfInterest.setEnd(
5762 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5763 Tokens[NumTokens-1])));
5764
Guy Benyei11169dd2012-12-18 14:30:41 +00005765 // Relex the tokens within the source range to look for preprocessing
5766 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005767 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005768
5769 // If begin location points inside a macro argument, set it to the expansion
5770 // location so we can have the full context when annotating semantically.
5771 {
5772 SourceManager &SM = CXXUnit->getSourceManager();
5773 SourceLocation Loc =
5774 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5775 if (Loc.isMacroID())
5776 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5777 }
5778
Guy Benyei11169dd2012-12-18 14:30:41 +00005779 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5780 // Search and mark tokens that are macro argument expansions.
5781 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5782 Tokens, NumTokens);
5783 CursorVisitor MacroArgMarker(TU,
5784 MarkMacroArgTokensVisitorDelegate, &Visitor,
5785 /*VisitPreprocessorLast=*/true,
5786 /*VisitIncludedEntities=*/false,
5787 RegionOfInterest);
5788 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5789 }
5790
5791 // Annotate all of the source locations in the region of interest that map to
5792 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005793 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005794
5795 // FIXME: We use a ridiculous stack size here because the data-recursion
5796 // algorithm uses a large stack frame than the non-data recursive version,
5797 // and AnnotationTokensWorker currently transforms the data-recursion
5798 // algorithm back into a traditional recursion by explicitly calling
5799 // VisitChildren(). We will need to remove this explicit recursive call.
5800 W.AnnotateTokens();
5801
5802 // If we ran into any entities that involve context-sensitive keywords,
5803 // take another pass through the tokens to mark them as such.
5804 if (W.hasContextSensitiveKeywords()) {
5805 for (unsigned I = 0; I != NumTokens; ++I) {
5806 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5807 continue;
5808
5809 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5810 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005811 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005812 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5813 if (Property->getPropertyAttributesAsWritten() != 0 &&
5814 llvm::StringSwitch<bool>(II->getName())
5815 .Case("readonly", true)
5816 .Case("assign", true)
5817 .Case("unsafe_unretained", true)
5818 .Case("readwrite", true)
5819 .Case("retain", true)
5820 .Case("copy", true)
5821 .Case("nonatomic", true)
5822 .Case("atomic", true)
5823 .Case("getter", true)
5824 .Case("setter", true)
5825 .Case("strong", true)
5826 .Case("weak", true)
5827 .Default(false))
5828 Tokens[I].int_data[0] = CXToken_Keyword;
5829 }
5830 continue;
5831 }
5832
5833 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5834 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5835 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5836 if (llvm::StringSwitch<bool>(II->getName())
5837 .Case("in", true)
5838 .Case("out", true)
5839 .Case("inout", true)
5840 .Case("oneway", true)
5841 .Case("bycopy", true)
5842 .Case("byref", true)
5843 .Default(false))
5844 Tokens[I].int_data[0] = CXToken_Keyword;
5845 continue;
5846 }
5847
5848 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5849 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5850 Tokens[I].int_data[0] = CXToken_Keyword;
5851 continue;
5852 }
5853 }
5854 }
5855}
5856
5857extern "C" {
5858
5859void clang_annotateTokens(CXTranslationUnit TU,
5860 CXToken *Tokens, unsigned NumTokens,
5861 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005862 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005863 LOG_BAD_TU(TU);
5864 return;
5865 }
5866 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005867 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005868 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005869 }
5870
5871 LOG_FUNC_SECTION {
5872 *Log << TU << ' ';
5873 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5874 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5875 *Log << clang_getRange(bloc, eloc);
5876 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005877
5878 // Any token we don't specifically annotate will have a NULL cursor.
5879 CXCursor C = clang_getNullCursor();
5880 for (unsigned I = 0; I != NumTokens; ++I)
5881 Cursors[I] = C;
5882
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005883 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005884 if (!CXXUnit)
5885 return;
5886
5887 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5888
5889 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5890 llvm::CrashRecoveryContext CRC;
5891 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5892 GetSafetyThreadStackSize() * 2)) {
5893 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5894 }
5895}
5896
5897} // end: extern "C"
5898
5899//===----------------------------------------------------------------------===//
5900// Operations for querying linkage of a cursor.
5901//===----------------------------------------------------------------------===//
5902
5903extern "C" {
5904CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5905 if (!clang_isDeclaration(cursor.kind))
5906 return CXLinkage_Invalid;
5907
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005908 const Decl *D = cxcursor::getCursorDecl(cursor);
5909 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005910 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005911 case NoLinkage:
5912 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005913 case InternalLinkage: return CXLinkage_Internal;
5914 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5915 case ExternalLinkage: return CXLinkage_External;
5916 };
5917
5918 return CXLinkage_Invalid;
5919}
5920} // end: extern "C"
5921
5922//===----------------------------------------------------------------------===//
5923// Operations for querying language of a cursor.
5924//===----------------------------------------------------------------------===//
5925
5926static CXLanguageKind getDeclLanguage(const Decl *D) {
5927 if (!D)
5928 return CXLanguage_C;
5929
5930 switch (D->getKind()) {
5931 default:
5932 break;
5933 case Decl::ImplicitParam:
5934 case Decl::ObjCAtDefsField:
5935 case Decl::ObjCCategory:
5936 case Decl::ObjCCategoryImpl:
5937 case Decl::ObjCCompatibleAlias:
5938 case Decl::ObjCImplementation:
5939 case Decl::ObjCInterface:
5940 case Decl::ObjCIvar:
5941 case Decl::ObjCMethod:
5942 case Decl::ObjCProperty:
5943 case Decl::ObjCPropertyImpl:
5944 case Decl::ObjCProtocol:
5945 return CXLanguage_ObjC;
5946 case Decl::CXXConstructor:
5947 case Decl::CXXConversion:
5948 case Decl::CXXDestructor:
5949 case Decl::CXXMethod:
5950 case Decl::CXXRecord:
5951 case Decl::ClassTemplate:
5952 case Decl::ClassTemplatePartialSpecialization:
5953 case Decl::ClassTemplateSpecialization:
5954 case Decl::Friend:
5955 case Decl::FriendTemplate:
5956 case Decl::FunctionTemplate:
5957 case Decl::LinkageSpec:
5958 case Decl::Namespace:
5959 case Decl::NamespaceAlias:
5960 case Decl::NonTypeTemplateParm:
5961 case Decl::StaticAssert:
5962 case Decl::TemplateTemplateParm:
5963 case Decl::TemplateTypeParm:
5964 case Decl::UnresolvedUsingTypename:
5965 case Decl::UnresolvedUsingValue:
5966 case Decl::Using:
5967 case Decl::UsingDirective:
5968 case Decl::UsingShadow:
5969 return CXLanguage_CPlusPlus;
5970 }
5971
5972 return CXLanguage_C;
5973}
5974
5975extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005976
5977static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5978 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5979 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005980
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005981 switch (D->getAvailability()) {
5982 case AR_Available:
5983 case AR_NotYetIntroduced:
5984 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005985 return getCursorAvailabilityForDecl(
5986 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005987 return CXAvailability_Available;
5988
5989 case AR_Deprecated:
5990 return CXAvailability_Deprecated;
5991
5992 case AR_Unavailable:
5993 return CXAvailability_NotAvailable;
5994 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005995
5996 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005997}
5998
Guy Benyei11169dd2012-12-18 14:30:41 +00005999enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6000 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006001 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6002 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006003
6004 return CXAvailability_Available;
6005}
6006
6007static CXVersion convertVersion(VersionTuple In) {
6008 CXVersion Out = { -1, -1, -1 };
6009 if (In.empty())
6010 return Out;
6011
6012 Out.Major = In.getMajor();
6013
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006014 Optional<unsigned> Minor = In.getMinor();
6015 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006016 Out.Minor = *Minor;
6017 else
6018 return Out;
6019
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006020 Optional<unsigned> Subminor = In.getSubminor();
6021 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006022 Out.Subminor = *Subminor;
6023
6024 return Out;
6025}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006026
6027static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6028 int *always_deprecated,
6029 CXString *deprecated_message,
6030 int *always_unavailable,
6031 CXString *unavailable_message,
6032 CXPlatformAvailability *availability,
6033 int availability_size) {
6034 bool HadAvailAttr = false;
6035 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006036 for (auto A : D->attrs()) {
6037 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006038 HadAvailAttr = true;
6039 if (always_deprecated)
6040 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006041 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006042 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006043 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006044 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006045 continue;
6046 }
6047
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006048 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006049 HadAvailAttr = true;
6050 if (always_unavailable)
6051 *always_unavailable = 1;
6052 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006053 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006054 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6055 }
6056 continue;
6057 }
6058
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006059 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006060 HadAvailAttr = true;
6061 if (N < availability_size) {
6062 availability[N].Platform
6063 = cxstring::createDup(Avail->getPlatform()->getName());
6064 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6065 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6066 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6067 availability[N].Unavailable = Avail->getUnavailable();
6068 availability[N].Message = cxstring::createDup(Avail->getMessage());
6069 }
6070 ++N;
6071 }
6072 }
6073
6074 if (!HadAvailAttr)
6075 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6076 return getCursorPlatformAvailabilityForDecl(
6077 cast<Decl>(EnumConst->getDeclContext()),
6078 always_deprecated,
6079 deprecated_message,
6080 always_unavailable,
6081 unavailable_message,
6082 availability,
6083 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006084
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006085 return N;
6086}
6087
Guy Benyei11169dd2012-12-18 14:30:41 +00006088int clang_getCursorPlatformAvailability(CXCursor cursor,
6089 int *always_deprecated,
6090 CXString *deprecated_message,
6091 int *always_unavailable,
6092 CXString *unavailable_message,
6093 CXPlatformAvailability *availability,
6094 int availability_size) {
6095 if (always_deprecated)
6096 *always_deprecated = 0;
6097 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006098 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006099 if (always_unavailable)
6100 *always_unavailable = 0;
6101 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006102 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006103
Guy Benyei11169dd2012-12-18 14:30:41 +00006104 if (!clang_isDeclaration(cursor.kind))
6105 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006106
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006107 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006108 if (!D)
6109 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006110
6111 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6112 deprecated_message,
6113 always_unavailable,
6114 unavailable_message,
6115 availability,
6116 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006117}
6118
6119void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6120 clang_disposeString(availability->Platform);
6121 clang_disposeString(availability->Message);
6122}
6123
6124CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6125 if (clang_isDeclaration(cursor.kind))
6126 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6127
6128 return CXLanguage_Invalid;
6129}
6130
6131 /// \brief If the given cursor is the "templated" declaration
6132 /// descibing a class or function template, return the class or
6133 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006134static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006135 if (!D)
6136 return 0;
6137
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006138 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006139 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6140 return FunTmpl;
6141
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006142 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006143 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6144 return ClassTmpl;
6145
6146 return D;
6147}
6148
6149CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6150 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006151 if (const Decl *D = getCursorDecl(cursor)) {
6152 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006153 if (!DC)
6154 return clang_getNullCursor();
6155
6156 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6157 getCursorTU(cursor));
6158 }
6159 }
6160
6161 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006162 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006163 return MakeCXCursor(D, getCursorTU(cursor));
6164 }
6165
6166 return clang_getNullCursor();
6167}
6168
6169CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6170 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006171 if (const Decl *D = getCursorDecl(cursor)) {
6172 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006173 if (!DC)
6174 return clang_getNullCursor();
6175
6176 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6177 getCursorTU(cursor));
6178 }
6179 }
6180
6181 // FIXME: Note that we can't easily compute the lexical context of a
6182 // statement or expression, so we return nothing.
6183 return clang_getNullCursor();
6184}
6185
6186CXFile clang_getIncludedFile(CXCursor cursor) {
6187 if (cursor.kind != CXCursor_InclusionDirective)
6188 return 0;
6189
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006190 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006191 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006192}
6193
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006194unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6195 if (C.kind != CXCursor_ObjCPropertyDecl)
6196 return CXObjCPropertyAttr_noattr;
6197
6198 unsigned Result = CXObjCPropertyAttr_noattr;
6199 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6200 ObjCPropertyDecl::PropertyAttributeKind Attr =
6201 PD->getPropertyAttributesAsWritten();
6202
6203#define SET_CXOBJCPROP_ATTR(A) \
6204 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6205 Result |= CXObjCPropertyAttr_##A
6206 SET_CXOBJCPROP_ATTR(readonly);
6207 SET_CXOBJCPROP_ATTR(getter);
6208 SET_CXOBJCPROP_ATTR(assign);
6209 SET_CXOBJCPROP_ATTR(readwrite);
6210 SET_CXOBJCPROP_ATTR(retain);
6211 SET_CXOBJCPROP_ATTR(copy);
6212 SET_CXOBJCPROP_ATTR(nonatomic);
6213 SET_CXOBJCPROP_ATTR(setter);
6214 SET_CXOBJCPROP_ATTR(atomic);
6215 SET_CXOBJCPROP_ATTR(weak);
6216 SET_CXOBJCPROP_ATTR(strong);
6217 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6218#undef SET_CXOBJCPROP_ATTR
6219
6220 return Result;
6221}
6222
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006223unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6224 if (!clang_isDeclaration(C.kind))
6225 return CXObjCDeclQualifier_None;
6226
6227 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6228 const Decl *D = getCursorDecl(C);
6229 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6230 QT = MD->getObjCDeclQualifier();
6231 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6232 QT = PD->getObjCDeclQualifier();
6233 if (QT == Decl::OBJC_TQ_None)
6234 return CXObjCDeclQualifier_None;
6235
6236 unsigned Result = CXObjCDeclQualifier_None;
6237 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6238 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6239 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6240 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6241 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6242 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6243
6244 return Result;
6245}
6246
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006247unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6248 if (!clang_isDeclaration(C.kind))
6249 return 0;
6250
6251 const Decl *D = getCursorDecl(C);
6252 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6253 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6254 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6255 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6256
6257 return 0;
6258}
6259
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006260unsigned clang_Cursor_isVariadic(CXCursor C) {
6261 if (!clang_isDeclaration(C.kind))
6262 return 0;
6263
6264 const Decl *D = getCursorDecl(C);
6265 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6266 return FD->isVariadic();
6267 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6268 return MD->isVariadic();
6269
6270 return 0;
6271}
6272
Guy Benyei11169dd2012-12-18 14:30:41 +00006273CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6274 if (!clang_isDeclaration(C.kind))
6275 return clang_getNullRange();
6276
6277 const Decl *D = getCursorDecl(C);
6278 ASTContext &Context = getCursorContext(C);
6279 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6280 if (!RC)
6281 return clang_getNullRange();
6282
6283 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6284}
6285
6286CXString clang_Cursor_getRawCommentText(CXCursor C) {
6287 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006288 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006289
6290 const Decl *D = getCursorDecl(C);
6291 ASTContext &Context = getCursorContext(C);
6292 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6293 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6294 StringRef();
6295
6296 // Don't duplicate the string because RawText points directly into source
6297 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006298 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006299}
6300
6301CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6302 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006303 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006304
6305 const Decl *D = getCursorDecl(C);
6306 const ASTContext &Context = getCursorContext(C);
6307 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6308
6309 if (RC) {
6310 StringRef BriefText = RC->getBriefText(Context);
6311
6312 // Don't duplicate the string because RawComment ensures that this memory
6313 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006314 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006315 }
6316
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006317 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006318}
6319
Guy Benyei11169dd2012-12-18 14:30:41 +00006320CXModule clang_Cursor_getModule(CXCursor C) {
6321 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006322 if (const ImportDecl *ImportD =
6323 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006324 return ImportD->getImportedModule();
6325 }
6326
6327 return 0;
6328}
6329
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006330CXFile clang_Module_getASTFile(CXModule CXMod) {
6331 if (!CXMod)
6332 return 0;
6333 Module *Mod = static_cast<Module*>(CXMod);
6334 return const_cast<FileEntry *>(Mod->getASTFile());
6335}
6336
Guy Benyei11169dd2012-12-18 14:30:41 +00006337CXModule clang_Module_getParent(CXModule CXMod) {
6338 if (!CXMod)
6339 return 0;
6340 Module *Mod = static_cast<Module*>(CXMod);
6341 return Mod->Parent;
6342}
6343
6344CXString clang_Module_getName(CXModule CXMod) {
6345 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006346 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006347 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006348 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006349}
6350
6351CXString clang_Module_getFullName(CXModule CXMod) {
6352 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006353 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006354 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006355 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006356}
6357
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006358unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6359 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006360 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006361 LOG_BAD_TU(TU);
6362 return 0;
6363 }
6364 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006365 return 0;
6366 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006367 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6368 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6369 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006370}
6371
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006372CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6373 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006374 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006375 LOG_BAD_TU(TU);
6376 return 0;
6377 }
6378 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006379 return 0;
6380 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006381 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006382
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006383 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6384 if (Index < TopHeaders.size())
6385 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006386
6387 return 0;
6388}
6389
6390} // end: extern "C"
6391
6392//===----------------------------------------------------------------------===//
6393// C++ AST instrospection.
6394//===----------------------------------------------------------------------===//
6395
6396extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006397unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6398 if (!clang_isDeclaration(C.kind))
6399 return 0;
6400
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006401 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006402 const CXXMethodDecl *Method =
6403 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006404 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6405}
6406
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006407unsigned clang_CXXMethod_isConst(CXCursor C) {
6408 if (!clang_isDeclaration(C.kind))
6409 return 0;
6410
6411 const Decl *D = cxcursor::getCursorDecl(C);
6412 const CXXMethodDecl *Method =
6413 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
6414 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6415}
6416
Guy Benyei11169dd2012-12-18 14:30:41 +00006417unsigned clang_CXXMethod_isStatic(CXCursor C) {
6418 if (!clang_isDeclaration(C.kind))
6419 return 0;
6420
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006421 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006422 const CXXMethodDecl *Method =
6423 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006424 return (Method && Method->isStatic()) ? 1 : 0;
6425}
6426
6427unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6428 if (!clang_isDeclaration(C.kind))
6429 return 0;
6430
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006431 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006432 const CXXMethodDecl *Method =
6433 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006434 return (Method && Method->isVirtual()) ? 1 : 0;
6435}
6436} // end: extern "C"
6437
6438//===----------------------------------------------------------------------===//
6439// Attribute introspection.
6440//===----------------------------------------------------------------------===//
6441
6442extern "C" {
6443CXType clang_getIBOutletCollectionType(CXCursor C) {
6444 if (C.kind != CXCursor_IBOutletCollectionAttr)
6445 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6446
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006447 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006448 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6449
6450 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6451}
6452} // end: extern "C"
6453
6454//===----------------------------------------------------------------------===//
6455// Inspecting memory usage.
6456//===----------------------------------------------------------------------===//
6457
6458typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6459
6460static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6461 enum CXTUResourceUsageKind k,
6462 unsigned long amount) {
6463 CXTUResourceUsageEntry entry = { k, amount };
6464 entries.push_back(entry);
6465}
6466
6467extern "C" {
6468
6469const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6470 const char *str = "";
6471 switch (kind) {
6472 case CXTUResourceUsage_AST:
6473 str = "ASTContext: expressions, declarations, and types";
6474 break;
6475 case CXTUResourceUsage_Identifiers:
6476 str = "ASTContext: identifiers";
6477 break;
6478 case CXTUResourceUsage_Selectors:
6479 str = "ASTContext: selectors";
6480 break;
6481 case CXTUResourceUsage_GlobalCompletionResults:
6482 str = "Code completion: cached global results";
6483 break;
6484 case CXTUResourceUsage_SourceManagerContentCache:
6485 str = "SourceManager: content cache allocator";
6486 break;
6487 case CXTUResourceUsage_AST_SideTables:
6488 str = "ASTContext: side tables";
6489 break;
6490 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6491 str = "SourceManager: malloc'ed memory buffers";
6492 break;
6493 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6494 str = "SourceManager: mmap'ed memory buffers";
6495 break;
6496 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6497 str = "ExternalASTSource: malloc'ed memory buffers";
6498 break;
6499 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6500 str = "ExternalASTSource: mmap'ed memory buffers";
6501 break;
6502 case CXTUResourceUsage_Preprocessor:
6503 str = "Preprocessor: malloc'ed memory";
6504 break;
6505 case CXTUResourceUsage_PreprocessingRecord:
6506 str = "Preprocessor: PreprocessingRecord";
6507 break;
6508 case CXTUResourceUsage_SourceManager_DataStructures:
6509 str = "SourceManager: data structures and tables";
6510 break;
6511 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6512 str = "Preprocessor: header search tables";
6513 break;
6514 }
6515 return str;
6516}
6517
6518CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006519 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006520 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006521 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6522 return usage;
6523 }
6524
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006525 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006526 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006527 ASTContext &astContext = astUnit->getASTContext();
6528
6529 // How much memory is used by AST nodes and types?
6530 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6531 (unsigned long) astContext.getASTAllocatedMemory());
6532
6533 // How much memory is used by identifiers?
6534 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6535 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6536
6537 // How much memory is used for selectors?
6538 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6539 (unsigned long) astContext.Selectors.getTotalMemory());
6540
6541 // How much memory is used by ASTContext's side tables?
6542 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6543 (unsigned long) astContext.getSideTableAllocatedMemory());
6544
6545 // How much memory is used for caching global code completion results?
6546 unsigned long completionBytes = 0;
6547 if (GlobalCodeCompletionAllocator *completionAllocator =
6548 astUnit->getCachedCompletionAllocator().getPtr()) {
6549 completionBytes = completionAllocator->getTotalMemory();
6550 }
6551 createCXTUResourceUsageEntry(*entries,
6552 CXTUResourceUsage_GlobalCompletionResults,
6553 completionBytes);
6554
6555 // How much memory is being used by SourceManager's content cache?
6556 createCXTUResourceUsageEntry(*entries,
6557 CXTUResourceUsage_SourceManagerContentCache,
6558 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6559
6560 // How much memory is being used by the MemoryBuffer's in SourceManager?
6561 const SourceManager::MemoryBufferSizes &srcBufs =
6562 astUnit->getSourceManager().getMemoryBufferSizes();
6563
6564 createCXTUResourceUsageEntry(*entries,
6565 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6566 (unsigned long) srcBufs.malloc_bytes);
6567 createCXTUResourceUsageEntry(*entries,
6568 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6569 (unsigned long) srcBufs.mmap_bytes);
6570 createCXTUResourceUsageEntry(*entries,
6571 CXTUResourceUsage_SourceManager_DataStructures,
6572 (unsigned long) astContext.getSourceManager()
6573 .getDataStructureSizes());
6574
6575 // How much memory is being used by the ExternalASTSource?
6576 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6577 const ExternalASTSource::MemoryBufferSizes &sizes =
6578 esrc->getMemoryBufferSizes();
6579
6580 createCXTUResourceUsageEntry(*entries,
6581 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6582 (unsigned long) sizes.malloc_bytes);
6583 createCXTUResourceUsageEntry(*entries,
6584 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6585 (unsigned long) sizes.mmap_bytes);
6586 }
6587
6588 // How much memory is being used by the Preprocessor?
6589 Preprocessor &pp = astUnit->getPreprocessor();
6590 createCXTUResourceUsageEntry(*entries,
6591 CXTUResourceUsage_Preprocessor,
6592 pp.getTotalMemory());
6593
6594 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6595 createCXTUResourceUsageEntry(*entries,
6596 CXTUResourceUsage_PreprocessingRecord,
6597 pRec->getTotalMemory());
6598 }
6599
6600 createCXTUResourceUsageEntry(*entries,
6601 CXTUResourceUsage_Preprocessor_HeaderSearch,
6602 pp.getHeaderSearchInfo().getTotalMemory());
6603
6604 CXTUResourceUsage usage = { (void*) entries.get(),
6605 (unsigned) entries->size(),
6606 entries->size() ? &(*entries)[0] : 0 };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006607 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006608 return usage;
6609}
6610
6611void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6612 if (usage.data)
6613 delete (MemUsageEntries*) usage.data;
6614}
6615
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006616CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6617 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006618 skipped->count = 0;
6619 skipped->ranges = 0;
6620
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006621 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006622 LOG_BAD_TU(TU);
6623 return skipped;
6624 }
6625
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006626 if (!file)
6627 return skipped;
6628
6629 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6630 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6631 if (!ppRec)
6632 return skipped;
6633
6634 ASTContext &Ctx = astUnit->getASTContext();
6635 SourceManager &sm = Ctx.getSourceManager();
6636 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6637 FileID wantedFileID = sm.translateFile(fileEntry);
6638
6639 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6640 std::vector<SourceRange> wantedRanges;
6641 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6642 i != ei; ++i) {
6643 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6644 wantedRanges.push_back(*i);
6645 }
6646
6647 skipped->count = wantedRanges.size();
6648 skipped->ranges = new CXSourceRange[skipped->count];
6649 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6650 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6651
6652 return skipped;
6653}
6654
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006655void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6656 if (ranges) {
6657 delete[] ranges->ranges;
6658 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006659 }
6660}
6661
Guy Benyei11169dd2012-12-18 14:30:41 +00006662} // end extern "C"
6663
6664void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6665 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6666 for (unsigned I = 0; I != Usage.numEntries; ++I)
6667 fprintf(stderr, " %s: %lu\n",
6668 clang_getTUResourceUsageName(Usage.entries[I].kind),
6669 Usage.entries[I].amount);
6670
6671 clang_disposeCXTUResourceUsage(Usage);
6672}
6673
6674//===----------------------------------------------------------------------===//
6675// Misc. utility functions.
6676//===----------------------------------------------------------------------===//
6677
6678/// Default to using an 8 MB stack size on "safety" threads.
6679static unsigned SafetyStackThreadSize = 8 << 20;
6680
6681namespace clang {
6682
6683bool RunSafely(llvm::CrashRecoveryContext &CRC,
6684 void (*Fn)(void*), void *UserData,
6685 unsigned Size) {
6686 if (!Size)
6687 Size = GetSafetyThreadStackSize();
6688 if (Size)
6689 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6690 return CRC.RunSafely(Fn, UserData);
6691}
6692
6693unsigned GetSafetyThreadStackSize() {
6694 return SafetyStackThreadSize;
6695}
6696
6697void SetSafetyThreadStackSize(unsigned Value) {
6698 SafetyStackThreadSize = Value;
6699}
6700
6701}
6702
6703void clang::setThreadBackgroundPriority() {
6704 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6705 return;
6706
6707 // FIXME: Move to llvm/Support and make it cross-platform.
6708#ifdef __APPLE__
6709 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6710#endif
6711}
6712
6713void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6714 if (!Unit)
6715 return;
6716
6717 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6718 DEnd = Unit->stored_diag_end();
6719 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006720 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006721 CXString Msg = clang_formatDiagnostic(&Diag,
6722 clang_defaultDiagnosticDisplayOptions());
6723 fprintf(stderr, "%s\n", clang_getCString(Msg));
6724 clang_disposeString(Msg);
6725 }
6726#ifdef LLVM_ON_WIN32
6727 // On Windows, force a flush, since there may be multiple copies of
6728 // stderr and stdout in the file system, all with different buffers
6729 // but writing to the same device.
6730 fflush(stderr);
6731#endif
6732}
6733
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006734MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6735 SourceLocation MacroDefLoc,
6736 CXTranslationUnit TU){
6737 if (MacroDefLoc.isInvalid() || !TU)
6738 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006739 if (!II.hadMacroDefinition())
6740 return 0;
6741
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006742 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006743 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006744 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006745 if (MD) {
6746 for (MacroDirective::DefInfo
6747 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6748 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6749 return Def.getMacroInfo();
6750 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006751 }
6752
6753 return 0;
6754}
6755
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006756const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6757 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006758 if (!MacroDef || !TU)
6759 return 0;
6760 const IdentifierInfo *II = MacroDef->getName();
6761 if (!II)
6762 return 0;
6763
6764 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6765}
6766
6767MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6768 const Token &Tok,
6769 CXTranslationUnit TU) {
6770 if (!MI || !TU)
6771 return 0;
6772 if (Tok.isNot(tok::raw_identifier))
6773 return 0;
6774
6775 if (MI->getNumTokens() == 0)
6776 return 0;
6777 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6778 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006779 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006780
6781 // Check that the token is inside the definition and not its argument list.
6782 SourceManager &SM = Unit->getSourceManager();
6783 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6784 return 0;
6785 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6786 return 0;
6787
6788 Preprocessor &PP = Unit->getPreprocessor();
6789 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6790 if (!PPRec)
6791 return 0;
6792
6793 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6794 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6795 if (!II.hadMacroDefinition())
6796 return 0;
6797
6798 // Check that the identifier is not one of the macro arguments.
6799 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6800 return 0;
6801
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006802 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6803 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006804 return 0;
6805
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006806 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006807}
6808
6809MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6810 SourceLocation Loc,
6811 CXTranslationUnit TU) {
6812 if (Loc.isInvalid() || !MI || !TU)
6813 return 0;
6814
6815 if (MI->getNumTokens() == 0)
6816 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006817 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006818 Preprocessor &PP = Unit->getPreprocessor();
6819 if (!PP.getPreprocessingRecord())
6820 return 0;
6821 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6822 Token Tok;
6823 if (PP.getRawToken(Loc, Tok))
6824 return 0;
6825
6826 return checkForMacroInMacroDefinition(MI, Tok, TU);
6827}
6828
Guy Benyei11169dd2012-12-18 14:30:41 +00006829extern "C" {
6830
6831CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006832 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006833}
6834
6835} // end: extern "C"
6836
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006837Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6838 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006839 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006840 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006841 if (Unit->isMainFileAST())
6842 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006843 return *this;
6844 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006845 } else {
6846 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006847 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006848 return *this;
6849}
6850
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006851Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6852 *this << FE->getName();
6853 return *this;
6854}
6855
6856Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6857 CXString cursorName = clang_getCursorDisplayName(cursor);
6858 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6859 clang_disposeString(cursorName);
6860 return *this;
6861}
6862
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006863Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6864 CXFile File;
6865 unsigned Line, Column;
6866 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6867 CXString FileName = clang_getFileName(File);
6868 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6869 clang_disposeString(FileName);
6870 return *this;
6871}
6872
6873Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6874 CXSourceLocation BLoc = clang_getRangeStart(range);
6875 CXSourceLocation ELoc = clang_getRangeEnd(range);
6876
6877 CXFile BFile;
6878 unsigned BLine, BColumn;
6879 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6880
6881 CXFile EFile;
6882 unsigned ELine, EColumn;
6883 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6884
6885 CXString BFileName = clang_getFileName(BFile);
6886 if (BFile == EFile) {
6887 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6888 BLine, BColumn, ELine, EColumn);
6889 } else {
6890 CXString EFileName = clang_getFileName(EFile);
6891 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6892 BLine, BColumn)
6893 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6894 ELine, EColumn);
6895 clang_disposeString(EFileName);
6896 }
6897 clang_disposeString(BFileName);
6898 return *this;
6899}
6900
6901Logger &cxindex::Logger::operator<<(CXString Str) {
6902 *this << clang_getCString(Str);
6903 return *this;
6904}
6905
6906Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6907 LogOS << Fmt;
6908 return *this;
6909}
6910
6911cxindex::Logger::~Logger() {
6912 LogOS.flush();
6913
6914 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6915
6916 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6917
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006918 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006919 OS << "[libclang:" << Name << ':';
6920
6921 // FIXME: Portability.
6922#if HAVE_PTHREAD_H && __APPLE__
6923 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6924 OS << tid << ':';
6925#endif
6926
6927 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6928 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6929 OS << Msg.str() << '\n';
6930
6931 if (Trace) {
6932 llvm::sys::PrintStackTrace(stderr);
6933 OS << "--------------------------------------------------\n";
6934 }
6935}