blob: 5710d66890df694791e9523295f5bb0bbef54b16 [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
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001940void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1941
Alexey Bataev756c1962013-09-24 03:17:45 +00001942template<typename T>
1943void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001944 for (const auto *I : Node->varlists())
1945 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001946}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001947
1948void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001949 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001950}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001951void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1952 const OMPFirstprivateClause *C) {
1953 VisitOMPClauseList(C);
1954}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001955void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001956 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001957}
Alexander Musman8dba6642014-04-22 13:09:42 +00001958void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
1959 VisitOMPClauseList(C);
1960 Visitor->AddStmt(C->getStep());
1961}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00001962void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
1963 VisitOMPClauseList(C);
1964}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001965}
Alexey Bataev756c1962013-09-24 03:17:45 +00001966
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001967void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1968 unsigned size = WL.size();
1969 OMPClauseEnqueue Visitor(this);
1970 Visitor.Visit(S);
1971 if (size == WL.size())
1972 return;
1973 // Now reverse the entries we just added. This will match the DFS
1974 // ordering performed by the worklist.
1975 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1976 std::reverse(I, E);
1977}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001978void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001979 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1980}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001981void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001982 AddDecl(B->getBlockDecl());
1983}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001984void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001985 EnqueueChildren(E);
1986 AddTypeLoc(E->getTypeSourceInfo());
1987}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001988void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1989 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001990 E = S->body_rend(); I != E; ++I) {
1991 AddStmt(*I);
1992 }
1993}
1994void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001995VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001996 AddStmt(S->getSubStmt());
1997 AddDeclarationNameInfo(S);
1998 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1999 AddNestedNameSpecifierLoc(QualifierLoc);
2000}
2001
2002void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002003VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002004 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2005 AddDeclarationNameInfo(E);
2006 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2007 AddNestedNameSpecifierLoc(QualifierLoc);
2008 if (!E->isImplicitAccess())
2009 AddStmt(E->getBase());
2010}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002011void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002012 // Enqueue the initializer , if any.
2013 AddStmt(E->getInitializer());
2014 // Enqueue the array size, if any.
2015 AddStmt(E->getArraySize());
2016 // Enqueue the allocated type.
2017 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2018 // Enqueue the placement arguments.
2019 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2020 AddStmt(E->getPlacementArg(I-1));
2021}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002022void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002023 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2024 AddStmt(CE->getArg(I-1));
2025 AddStmt(CE->getCallee());
2026 AddStmt(CE->getArg(0));
2027}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002028void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2029 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002030 // Visit the name of the type being destroyed.
2031 AddTypeLoc(E->getDestroyedTypeInfo());
2032 // Visit the scope type that looks disturbingly like the nested-name-specifier
2033 // but isn't.
2034 AddTypeLoc(E->getScopeTypeInfo());
2035 // Visit the nested-name-specifier.
2036 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2037 AddNestedNameSpecifierLoc(QualifierLoc);
2038 // Visit base expression.
2039 AddStmt(E->getBase());
2040}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002041void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2042 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002043 AddTypeLoc(E->getTypeSourceInfo());
2044}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002045void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2046 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002047 EnqueueChildren(E);
2048 AddTypeLoc(E->getTypeSourceInfo());
2049}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002050void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002051 EnqueueChildren(E);
2052 if (E->isTypeOperand())
2053 AddTypeLoc(E->getTypeOperandSourceInfo());
2054}
2055
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002056void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2057 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002058 EnqueueChildren(E);
2059 AddTypeLoc(E->getTypeSourceInfo());
2060}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002061void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002062 EnqueueChildren(E);
2063 if (E->isTypeOperand())
2064 AddTypeLoc(E->getTypeOperandSourceInfo());
2065}
2066
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002067void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002068 EnqueueChildren(S);
2069 AddDecl(S->getExceptionDecl());
2070}
2071
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002072void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002073 if (DR->hasExplicitTemplateArgs()) {
2074 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2075 }
2076 WL.push_back(DeclRefExprParts(DR, Parent));
2077}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002078void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2079 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002080 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2081 AddDeclarationNameInfo(E);
2082 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2083}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002084void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002085 unsigned size = WL.size();
2086 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002087 for (const auto *D : S->decls()) {
2088 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002089 isFirst = false;
2090 }
2091 if (size == WL.size())
2092 return;
2093 // Now reverse the entries we just added. This will match the DFS
2094 // ordering performed by the worklist.
2095 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2096 std::reverse(I, E);
2097}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002098void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002099 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002100 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002101 D = E->designators_rbegin(), DEnd = E->designators_rend();
2102 D != DEnd; ++D) {
2103 if (D->isFieldDesignator()) {
2104 if (FieldDecl *Field = D->getField())
2105 AddMemberRef(Field, D->getFieldLoc());
2106 continue;
2107 }
2108 if (D->isArrayDesignator()) {
2109 AddStmt(E->getArrayIndex(*D));
2110 continue;
2111 }
2112 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2113 AddStmt(E->getArrayRangeEnd(*D));
2114 AddStmt(E->getArrayRangeStart(*D));
2115 }
2116}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002117void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002118 EnqueueChildren(E);
2119 AddTypeLoc(E->getTypeInfoAsWritten());
2120}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002121void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002122 AddStmt(FS->getBody());
2123 AddStmt(FS->getInc());
2124 AddStmt(FS->getCond());
2125 AddDecl(FS->getConditionVariable());
2126 AddStmt(FS->getInit());
2127}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002128void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002129 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2130}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002131void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002132 AddStmt(If->getElse());
2133 AddStmt(If->getThen());
2134 AddStmt(If->getCond());
2135 AddDecl(If->getConditionVariable());
2136}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002137void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002138 // We care about the syntactic form of the initializer list, only.
2139 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2140 IE = Syntactic;
2141 EnqueueChildren(IE);
2142}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002143void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002144 WL.push_back(MemberExprParts(M, Parent));
2145
2146 // If the base of the member access expression is an implicit 'this', don't
2147 // visit it.
2148 // FIXME: If we ever want to show these implicit accesses, this will be
2149 // unfortunate. However, clang_getCursor() relies on this behavior.
2150 if (!M->isImplicitAccess())
2151 AddStmt(M->getBase());
2152}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002153void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002154 AddTypeLoc(E->getEncodedTypeSourceInfo());
2155}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002156void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002157 EnqueueChildren(M);
2158 AddTypeLoc(M->getClassReceiverTypeInfo());
2159}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002160void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002161 // Visit the components of the offsetof expression.
2162 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2163 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2164 const OffsetOfNode &Node = E->getComponent(I-1);
2165 switch (Node.getKind()) {
2166 case OffsetOfNode::Array:
2167 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2168 break;
2169 case OffsetOfNode::Field:
2170 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2171 break;
2172 case OffsetOfNode::Identifier:
2173 case OffsetOfNode::Base:
2174 continue;
2175 }
2176 }
2177 // Visit the type into which we're computing the offset.
2178 AddTypeLoc(E->getTypeSourceInfo());
2179}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002180void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002181 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2182 WL.push_back(OverloadExprParts(E, Parent));
2183}
2184void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002185 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002186 EnqueueChildren(E);
2187 if (E->isArgumentType())
2188 AddTypeLoc(E->getArgumentTypeInfo());
2189}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002190void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002191 EnqueueChildren(S);
2192}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002193void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002194 AddStmt(S->getBody());
2195 AddStmt(S->getCond());
2196 AddDecl(S->getConditionVariable());
2197}
2198
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002199void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002200 AddStmt(W->getBody());
2201 AddStmt(W->getCond());
2202 AddDecl(W->getConditionVariable());
2203}
2204
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002205void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002206 for (unsigned I = E->getNumArgs(); I > 0; --I)
2207 AddTypeLoc(E->getArg(I-1));
2208}
2209
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002210void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002211 AddTypeLoc(E->getQueriedTypeSourceInfo());
2212}
2213
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002214void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002215 EnqueueChildren(E);
2216}
2217
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 VisitOverloadExpr(U);
2220 if (!U->isImplicitAccess())
2221 AddStmt(U->getBase());
2222}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002223void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002224 AddStmt(E->getSubExpr());
2225 AddTypeLoc(E->getWrittenTypeInfo());
2226}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002227void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002228 WL.push_back(SizeOfPackExprParts(E, Parent));
2229}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002230void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002231 // If the opaque value has a source expression, just transparently
2232 // visit that. This is useful for (e.g.) pseudo-object expressions.
2233 if (Expr *SourceExpr = E->getSourceExpr())
2234 return Visit(SourceExpr);
2235}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002236void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002237 AddStmt(E->getBody());
2238 WL.push_back(LambdaExprParts(E, Parent));
2239}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002240void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002241 // Treat the expression like its syntactic form.
2242 Visit(E->getSyntacticForm());
2243}
2244
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002245void EnqueueVisitor::VisitOMPExecutableDirective(
2246 const OMPExecutableDirective *D) {
2247 EnqueueChildren(D);
2248 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2249 E = D->clauses().end();
2250 I != E; ++I)
2251 EnqueueChildren(*I);
2252}
2253
2254void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2255 VisitOMPExecutableDirective(D);
2256}
2257
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002258void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2259 VisitOMPExecutableDirective(D);
2260}
2261
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002262void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002263 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2264}
2265
2266bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2267 if (RegionOfInterest.isValid()) {
2268 SourceRange Range = getRawCursorExtent(C);
2269 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2270 return false;
2271 }
2272 return true;
2273}
2274
2275bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2276 while (!WL.empty()) {
2277 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002278 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002279
2280 // Set the Parent field, then back to its old value once we're done.
2281 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2282
2283 switch (LI.getKind()) {
2284 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002285 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002286 if (!D)
2287 continue;
2288
2289 // For now, perform default visitation for Decls.
2290 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2291 cast<DeclVisit>(&LI)->isFirst())))
2292 return true;
2293
2294 continue;
2295 }
2296 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2297 const ASTTemplateArgumentListInfo *ArgList =
2298 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2299 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2300 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2301 Arg != ArgEnd; ++Arg) {
2302 if (VisitTemplateArgumentLoc(*Arg))
2303 return true;
2304 }
2305 continue;
2306 }
2307 case VisitorJob::TypeLocVisitKind: {
2308 // Perform default visitation for TypeLocs.
2309 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2310 return true;
2311 continue;
2312 }
2313 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002314 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002315 if (LabelStmt *stmt = LS->getStmt()) {
2316 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2317 TU))) {
2318 return true;
2319 }
2320 }
2321 continue;
2322 }
2323
2324 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2325 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2326 if (VisitNestedNameSpecifierLoc(V->get()))
2327 return true;
2328 continue;
2329 }
2330
2331 case VisitorJob::DeclarationNameInfoVisitKind: {
2332 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2333 ->get()))
2334 return true;
2335 continue;
2336 }
2337 case VisitorJob::MemberRefVisitKind: {
2338 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2339 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2340 return true;
2341 continue;
2342 }
2343 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002344 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002345 if (!S)
2346 continue;
2347
2348 // Update the current cursor.
2349 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2350 if (!IsInRegionOfInterest(Cursor))
2351 continue;
2352 switch (Visitor(Cursor, Parent, ClientData)) {
2353 case CXChildVisit_Break: return true;
2354 case CXChildVisit_Continue: break;
2355 case CXChildVisit_Recurse:
2356 if (PostChildrenVisitor)
2357 WL.push_back(PostChildrenVisit(0, Cursor));
2358 EnqueueWorkList(WL, S);
2359 break;
2360 }
2361 continue;
2362 }
2363 case VisitorJob::MemberExprPartsKind: {
2364 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002365 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002366
2367 // Visit the nested-name-specifier
2368 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2369 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2370 return true;
2371
2372 // Visit the declaration name.
2373 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2374 return true;
2375
2376 // Visit the explicitly-specified template arguments, if any.
2377 if (M->hasExplicitTemplateArgs()) {
2378 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2379 *ArgEnd = Arg + M->getNumTemplateArgs();
2380 Arg != ArgEnd; ++Arg) {
2381 if (VisitTemplateArgumentLoc(*Arg))
2382 return true;
2383 }
2384 }
2385 continue;
2386 }
2387 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002388 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002389 // Visit nested-name-specifier, if present.
2390 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2391 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2392 return true;
2393 // Visit declaration name.
2394 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2395 return true;
2396 continue;
2397 }
2398 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002399 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002400 // Visit the nested-name-specifier.
2401 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2402 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2403 return true;
2404 // Visit the declaration name.
2405 if (VisitDeclarationNameInfo(O->getNameInfo()))
2406 return true;
2407 // Visit the overloaded declaration reference.
2408 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2409 return true;
2410 continue;
2411 }
2412 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002413 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002414 NamedDecl *Pack = E->getPack();
2415 if (isa<TemplateTypeParmDecl>(Pack)) {
2416 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2417 E->getPackLoc(), TU)))
2418 return true;
2419
2420 continue;
2421 }
2422
2423 if (isa<TemplateTemplateParmDecl>(Pack)) {
2424 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2425 E->getPackLoc(), TU)))
2426 return true;
2427
2428 continue;
2429 }
2430
2431 // Non-type template parameter packs and function parameter packs are
2432 // treated like DeclRefExpr cursors.
2433 continue;
2434 }
2435
2436 case VisitorJob::LambdaExprPartsKind: {
2437 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002438 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002439 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2440 CEnd = E->explicit_capture_end();
2441 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002442 // FIXME: Lambda init-captures.
2443 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002444 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002445
Guy Benyei11169dd2012-12-18 14:30:41 +00002446 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2447 C->getLocation(),
2448 TU)))
2449 return true;
2450 }
2451
2452 // Visit parameters and return type, if present.
2453 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2454 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2455 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2456 // Visit the whole type.
2457 if (Visit(TL))
2458 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002459 } else if (FunctionProtoTypeLoc Proto =
2460 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002461 if (E->hasExplicitParameters()) {
2462 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002463 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2464 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002465 return true;
2466 } else {
2467 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002468 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002469 return true;
2470 }
2471 }
2472 }
2473 break;
2474 }
2475
2476 case VisitorJob::PostChildrenVisitKind:
2477 if (PostChildrenVisitor(Parent, ClientData))
2478 return true;
2479 break;
2480 }
2481 }
2482 return false;
2483}
2484
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002485bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002486 VisitorWorkList *WL = 0;
2487 if (!WorkListFreeList.empty()) {
2488 WL = WorkListFreeList.back();
2489 WL->clear();
2490 WorkListFreeList.pop_back();
2491 }
2492 else {
2493 WL = new VisitorWorkList();
2494 WorkListCache.push_back(WL);
2495 }
2496 EnqueueWorkList(*WL, S);
2497 bool result = RunVisitorWorkList(*WL);
2498 WorkListFreeList.push_back(WL);
2499 return result;
2500}
2501
2502namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002503typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002504RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2505 const DeclarationNameInfo &NI,
2506 const SourceRange &QLoc,
2507 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2508 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2509 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2510 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2511
2512 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2513
2514 RefNamePieces Pieces;
2515
2516 if (WantQualifier && QLoc.isValid())
2517 Pieces.push_back(QLoc);
2518
2519 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2520 Pieces.push_back(NI.getLoc());
2521
2522 if (WantTemplateArgs && TemplateArgs)
2523 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2524 TemplateArgs->RAngleLoc));
2525
2526 if (Kind == DeclarationName::CXXOperatorName) {
2527 Pieces.push_back(SourceLocation::getFromRawEncoding(
2528 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2529 Pieces.push_back(SourceLocation::getFromRawEncoding(
2530 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2531 }
2532
2533 if (WantSinglePiece) {
2534 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2535 Pieces.clear();
2536 Pieces.push_back(R);
2537 }
2538
2539 return Pieces;
2540}
2541}
2542
2543//===----------------------------------------------------------------------===//
2544// Misc. API hooks.
2545//===----------------------------------------------------------------------===//
2546
2547static llvm::sys::Mutex EnableMultithreadingMutex;
2548static bool EnabledMultithreading;
2549
Chad Rosier05c71aa2013-03-27 18:28:23 +00002550static void fatal_error_handler(void *user_data, const std::string& reason,
2551 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002552 // Write the result out to stderr avoiding errs() because raw_ostreams can
2553 // call report_fatal_error.
2554 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2555 ::abort();
2556}
2557
2558extern "C" {
2559CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2560 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002561 // We use crash recovery to make some of our APIs more reliable, implicitly
2562 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002563 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2564 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002565
2566 // Enable support for multithreading in LLVM.
2567 {
2568 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2569 if (!EnabledMultithreading) {
2570 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2571 llvm::llvm_start_multithreaded();
2572 EnabledMultithreading = true;
2573 }
2574 }
2575
2576 CIndexer *CIdxr = new CIndexer();
2577 if (excludeDeclarationsFromPCH)
2578 CIdxr->setOnlyLocalDecls();
2579 if (displayDiagnostics)
2580 CIdxr->setDisplayDiagnostics();
2581
2582 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2583 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2584 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2585 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2586 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2587 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2588
2589 return CIdxr;
2590}
2591
2592void clang_disposeIndex(CXIndex CIdx) {
2593 if (CIdx)
2594 delete static_cast<CIndexer *>(CIdx);
2595}
2596
2597void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2598 if (CIdx)
2599 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2600}
2601
2602unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2603 if (CIdx)
2604 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2605 return 0;
2606}
2607
2608void clang_toggleCrashRecovery(unsigned isEnabled) {
2609 if (isEnabled)
2610 llvm::CrashRecoveryContext::Enable();
2611 else
2612 llvm::CrashRecoveryContext::Disable();
2613}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002614
Guy Benyei11169dd2012-12-18 14:30:41 +00002615CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2616 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002617 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002618 enum CXErrorCode Result =
2619 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002620 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002621 assert((TU && Result == CXError_Success) ||
2622 (!TU && Result != CXError_Success));
2623 return TU;
2624}
2625
2626enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2627 const char *ast_filename,
2628 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002629 if (out_TU)
2630 *out_TU = NULL;
2631
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002632 if (!CIdx || !ast_filename || !out_TU)
2633 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002634
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002635 LOG_FUNC_SECTION {
2636 *Log << ast_filename;
2637 }
2638
Guy Benyei11169dd2012-12-18 14:30:41 +00002639 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2640 FileSystemOptions FileSystemOpts;
2641
2642 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002643 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002644 CXXIdx->getOnlyLocalDecls(), None,
2645 /*CaptureDiagnostics=*/true,
2646 /*AllowPCHWithCompilerErrors=*/true,
2647 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002648 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2649 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002650}
2651
2652unsigned clang_defaultEditingTranslationUnitOptions() {
2653 return CXTranslationUnit_PrecompiledPreamble |
2654 CXTranslationUnit_CacheCompletionResults;
2655}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002656
Guy Benyei11169dd2012-12-18 14:30:41 +00002657CXTranslationUnit
2658clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2659 const char *source_filename,
2660 int num_command_line_args,
2661 const char * const *command_line_args,
2662 unsigned num_unsaved_files,
2663 struct CXUnsavedFile *unsaved_files) {
2664 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2665 return clang_parseTranslationUnit(CIdx, source_filename,
2666 command_line_args, num_command_line_args,
2667 unsaved_files, num_unsaved_files,
2668 Options);
2669}
2670
2671struct ParseTranslationUnitInfo {
2672 CXIndex CIdx;
2673 const char *source_filename;
2674 const char *const *command_line_args;
2675 int num_command_line_args;
2676 struct CXUnsavedFile *unsaved_files;
2677 unsigned num_unsaved_files;
2678 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002679 CXTranslationUnit *out_TU;
2680 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002681};
2682static void clang_parseTranslationUnit_Impl(void *UserData) {
2683 ParseTranslationUnitInfo *PTUI =
2684 static_cast<ParseTranslationUnitInfo*>(UserData);
2685 CXIndex CIdx = PTUI->CIdx;
2686 const char *source_filename = PTUI->source_filename;
2687 const char * const *command_line_args = PTUI->command_line_args;
2688 int num_command_line_args = PTUI->num_command_line_args;
2689 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2690 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2691 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002692 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002693
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002694 // Set up the initial return values.
2695 if (out_TU)
2696 *out_TU = NULL;
2697 PTUI->result = CXError_Failure;
2698
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002699 // Check arguments.
2700 if (!CIdx || !out_TU ||
2701 (unsaved_files == NULL && num_unsaved_files != 0)) {
2702 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002703 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002704 }
2705
Guy Benyei11169dd2012-12-18 14:30:41 +00002706 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2707
2708 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2709 setThreadBackgroundPriority();
2710
2711 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2712 // FIXME: Add a flag for modules.
2713 TranslationUnitKind TUKind
2714 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002715 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002716 = options & CXTranslationUnit_CacheCompletionResults;
2717 bool IncludeBriefCommentsInCodeCompletion
2718 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2719 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2720 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2721
2722 // Configure the diagnostics.
2723 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002724 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002725
2726 // Recover resources if we crash before exiting this function.
2727 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2728 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2729 DiagCleanup(Diags.getPtr());
2730
Ahmed Charlesb8984322014-03-07 20:03:18 +00002731 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2732 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002733
2734 // Recover resources if we crash before exiting this function.
2735 llvm::CrashRecoveryContextCleanupRegistrar<
2736 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2737
2738 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2739 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2740 const llvm::MemoryBuffer *Buffer
2741 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2742 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2743 Buffer));
2744 }
2745
Ahmed Charlesb8984322014-03-07 20:03:18 +00002746 std::unique_ptr<std::vector<const char *>> Args(
2747 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002748
2749 // Recover resources if we crash before exiting this method.
2750 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2751 ArgsCleanup(Args.get());
2752
2753 // Since the Clang C library is primarily used by batch tools dealing with
2754 // (often very broken) source code, where spell-checking can have a
2755 // significant negative impact on performance (particularly when
2756 // precompiled headers are involved), we disable it by default.
2757 // Only do this if we haven't found a spell-checking-related argument.
2758 bool FoundSpellCheckingArgument = false;
2759 for (int I = 0; I != num_command_line_args; ++I) {
2760 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2761 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2762 FoundSpellCheckingArgument = true;
2763 break;
2764 }
2765 }
2766 if (!FoundSpellCheckingArgument)
2767 Args->push_back("-fno-spell-checking");
2768
2769 Args->insert(Args->end(), command_line_args,
2770 command_line_args + num_command_line_args);
2771
2772 // The 'source_filename' argument is optional. If the caller does not
2773 // specify it then it is assumed that the source file is specified
2774 // in the actual argument list.
2775 // Put the source file after command_line_args otherwise if '-x' flag is
2776 // present it will be unused.
2777 if (source_filename)
2778 Args->push_back(source_filename);
2779
2780 // Do we need the detailed preprocessing record?
2781 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2782 Args->push_back("-Xclang");
2783 Args->push_back("-detailed-preprocessing-record");
2784 }
2785
2786 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002787 std::unique_ptr<ASTUnit> ErrUnit;
2788 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002789 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002790 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2791 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2792 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2793 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2794 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2795 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002796
2797 if (NumErrors != Diags->getClient()->getNumErrors()) {
2798 // Make sure to check that 'Unit' is non-NULL.
2799 if (CXXIdx->getDisplayDiagnostics())
2800 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2801 }
2802
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002803 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2804 PTUI->result = CXError_ASTReadError;
2805 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002806 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002807 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2808 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002809}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002810
2811CXTranslationUnit
2812clang_parseTranslationUnit(CXIndex CIdx,
2813 const char *source_filename,
2814 const char *const *command_line_args,
2815 int num_command_line_args,
2816 struct CXUnsavedFile *unsaved_files,
2817 unsigned num_unsaved_files,
2818 unsigned options) {
2819 CXTranslationUnit TU;
2820 enum CXErrorCode Result = clang_parseTranslationUnit2(
2821 CIdx, source_filename, command_line_args, num_command_line_args,
2822 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002823 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002824 assert((TU && Result == CXError_Success) ||
2825 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002826 return TU;
2827}
2828
2829enum CXErrorCode clang_parseTranslationUnit2(
2830 CXIndex CIdx,
2831 const char *source_filename,
2832 const char *const *command_line_args,
2833 int num_command_line_args,
2834 struct CXUnsavedFile *unsaved_files,
2835 unsigned num_unsaved_files,
2836 unsigned options,
2837 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002838 LOG_FUNC_SECTION {
2839 *Log << source_filename << ": ";
2840 for (int i = 0; i != num_command_line_args; ++i)
2841 *Log << command_line_args[i] << " ";
2842 }
2843
Guy Benyei11169dd2012-12-18 14:30:41 +00002844 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2845 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002846 num_unsaved_files, options, out_TU,
2847 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002848 llvm::CrashRecoveryContext CRC;
2849
2850 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2851 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2852 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2853 fprintf(stderr, " 'command_line_args' : [");
2854 for (int i = 0; i != num_command_line_args; ++i) {
2855 if (i)
2856 fprintf(stderr, ", ");
2857 fprintf(stderr, "'%s'", command_line_args[i]);
2858 }
2859 fprintf(stderr, "],\n");
2860 fprintf(stderr, " 'unsaved_files' : [");
2861 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2862 if (i)
2863 fprintf(stderr, ", ");
2864 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2865 unsaved_files[i].Length);
2866 }
2867 fprintf(stderr, "],\n");
2868 fprintf(stderr, " 'options' : %d,\n", options);
2869 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002870
2871 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002872 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002873 if (CXTranslationUnit *TU = PTUI.out_TU)
2874 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002875 }
2876
2877 return PTUI.result;
2878}
2879
2880unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2881 return CXSaveTranslationUnit_None;
2882}
2883
2884namespace {
2885
2886struct SaveTranslationUnitInfo {
2887 CXTranslationUnit TU;
2888 const char *FileName;
2889 unsigned options;
2890 CXSaveError result;
2891};
2892
2893}
2894
2895static void clang_saveTranslationUnit_Impl(void *UserData) {
2896 SaveTranslationUnitInfo *STUI =
2897 static_cast<SaveTranslationUnitInfo*>(UserData);
2898
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002899 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002900 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2901 setThreadBackgroundPriority();
2902
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002903 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002904 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2905}
2906
2907int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2908 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002909 LOG_FUNC_SECTION {
2910 *Log << TU << ' ' << FileName;
2911 }
2912
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002913 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002914 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002915 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002916 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002917
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002918 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002919 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2920 if (!CXXUnit->hasSema())
2921 return CXSaveError_InvalidTU;
2922
2923 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2924
2925 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2926 getenv("LIBCLANG_NOTHREADS")) {
2927 clang_saveTranslationUnit_Impl(&STUI);
2928
2929 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2930 PrintLibclangResourceUsage(TU);
2931
2932 return STUI.result;
2933 }
2934
2935 // We have an AST that has invalid nodes due to compiler errors.
2936 // Use a crash recovery thread for protection.
2937
2938 llvm::CrashRecoveryContext CRC;
2939
2940 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2941 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2942 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2943 fprintf(stderr, " 'options' : %d,\n", options);
2944 fprintf(stderr, "}\n");
2945
2946 return CXSaveError_Unknown;
2947
2948 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2949 PrintLibclangResourceUsage(TU);
2950 }
2951
2952 return STUI.result;
2953}
2954
2955void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2956 if (CTUnit) {
2957 // If the translation unit has been marked as unsafe to free, just discard
2958 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002959 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2960 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002961 return;
2962
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002963 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002964 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002965 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2966 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002967 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002968 delete CTUnit;
2969 }
2970}
2971
2972unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2973 return CXReparse_None;
2974}
2975
2976struct ReparseTranslationUnitInfo {
2977 CXTranslationUnit TU;
2978 unsigned num_unsaved_files;
2979 struct CXUnsavedFile *unsaved_files;
2980 unsigned options;
2981 int result;
2982};
2983
2984static void clang_reparseTranslationUnit_Impl(void *UserData) {
2985 ReparseTranslationUnitInfo *RTUI =
2986 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002987 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002988
Guy Benyei11169dd2012-12-18 14:30:41 +00002989 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002990 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2991 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2992 unsigned options = RTUI->options;
2993 (void) options;
2994
2995 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002996 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002997 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002998 RTUI->result = CXError_InvalidArguments;
2999 return;
3000 }
3001 if (unsaved_files == NULL && num_unsaved_files != 0) {
3002 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003003 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003004 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003005
3006 // Reset the associated diagnostics.
3007 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3008 TU->Diagnostics = 0;
3009
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003010 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003011 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3012 setThreadBackgroundPriority();
3013
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003014 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003015 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003016
3017 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3018 new std::vector<ASTUnit::RemappedFile>());
3019
Guy Benyei11169dd2012-12-18 14:30:41 +00003020 // Recover resources if we crash before exiting this function.
3021 llvm::CrashRecoveryContextCleanupRegistrar<
3022 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3023
3024 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3025 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3026 const llvm::MemoryBuffer *Buffer
3027 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3028 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3029 Buffer));
3030 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003031
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003032 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003033 RTUI->result = CXError_Success;
3034 else if (isASTReadError(CXXUnit))
3035 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003036}
3037
3038int clang_reparseTranslationUnit(CXTranslationUnit TU,
3039 unsigned num_unsaved_files,
3040 struct CXUnsavedFile *unsaved_files,
3041 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003042 LOG_FUNC_SECTION {
3043 *Log << TU;
3044 }
3045
Guy Benyei11169dd2012-12-18 14:30:41 +00003046 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003047 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003048
3049 if (getenv("LIBCLANG_NOTHREADS")) {
3050 clang_reparseTranslationUnit_Impl(&RTUI);
3051 return RTUI.result;
3052 }
3053
3054 llvm::CrashRecoveryContext CRC;
3055
3056 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3057 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003058 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003059 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003060 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3061 PrintLibclangResourceUsage(TU);
3062
3063 return RTUI.result;
3064}
3065
3066
3067CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003068 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003069 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003070 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003071 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003072
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003073 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003074 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003075}
3076
3077CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003078 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003079 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003080 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003081 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003082
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003083 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003084 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3085}
3086
3087} // end: extern "C"
3088
3089//===----------------------------------------------------------------------===//
3090// CXFile Operations.
3091//===----------------------------------------------------------------------===//
3092
3093extern "C" {
3094CXString clang_getFileName(CXFile SFile) {
3095 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003096 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003097
3098 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003099 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003100}
3101
3102time_t clang_getFileTime(CXFile SFile) {
3103 if (!SFile)
3104 return 0;
3105
3106 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3107 return FEnt->getModificationTime();
3108}
3109
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003110CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003111 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003112 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003113 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003114 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003115
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003116 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003117
3118 FileManager &FMgr = CXXUnit->getFileManager();
3119 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3120}
3121
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003122unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3123 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003124 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003125 LOG_BAD_TU(TU);
3126 return 0;
3127 }
3128
3129 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003130 return 0;
3131
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003132 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003133 FileEntry *FEnt = static_cast<FileEntry *>(file);
3134 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3135 .isFileMultipleIncludeGuarded(FEnt);
3136}
3137
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003138int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3139 if (!file || !outID)
3140 return 1;
3141
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003142 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003143 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3144 outID->data[0] = ID.getDevice();
3145 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003146 outID->data[2] = FEnt->getModificationTime();
3147 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003148}
3149
Guy Benyei11169dd2012-12-18 14:30:41 +00003150} // end: extern "C"
3151
3152//===----------------------------------------------------------------------===//
3153// CXCursor Operations.
3154//===----------------------------------------------------------------------===//
3155
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003156static const Decl *getDeclFromExpr(const Stmt *E) {
3157 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003158 return getDeclFromExpr(CE->getSubExpr());
3159
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003160 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003161 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003162 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003163 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003164 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003165 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003166 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003167 if (PRE->isExplicitProperty())
3168 return PRE->getExplicitProperty();
3169 // It could be messaging both getter and setter as in:
3170 // ++myobj.myprop;
3171 // in which case prefer to associate the setter since it is less obvious
3172 // from inspecting the source that the setter is going to get called.
3173 if (PRE->isMessagingSetter())
3174 return PRE->getImplicitPropertySetter();
3175 return PRE->getImplicitPropertyGetter();
3176 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003177 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003178 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003179 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003180 if (Expr *Src = OVE->getSourceExpr())
3181 return getDeclFromExpr(Src);
3182
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003183 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003184 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003185 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003186 if (!CE->isElidable())
3187 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003188 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003189 return OME->getMethodDecl();
3190
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003191 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003192 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003193 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003194 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3195 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003196 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003197 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3198 isa<ParmVarDecl>(SizeOfPack->getPack()))
3199 return SizeOfPack->getPack();
3200
3201 return 0;
3202}
3203
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003204static SourceLocation getLocationFromExpr(const Expr *E) {
3205 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003206 return getLocationFromExpr(CE->getSubExpr());
3207
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003208 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003209 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003210 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003211 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003212 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003213 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003214 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003215 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003216 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003217 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003218 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003219 return PropRef->getLocation();
3220
3221 return E->getLocStart();
3222}
3223
3224extern "C" {
3225
3226unsigned clang_visitChildren(CXCursor parent,
3227 CXCursorVisitor visitor,
3228 CXClientData client_data) {
3229 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3230 /*VisitPreprocessorLast=*/false);
3231 return CursorVis.VisitChildren(parent);
3232}
3233
3234#ifndef __has_feature
3235#define __has_feature(x) 0
3236#endif
3237#if __has_feature(blocks)
3238typedef enum CXChildVisitResult
3239 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3240
3241static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3242 CXClientData client_data) {
3243 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3244 return block(cursor, parent);
3245}
3246#else
3247// If we are compiled with a compiler that doesn't have native blocks support,
3248// define and call the block manually, so the
3249typedef struct _CXChildVisitResult
3250{
3251 void *isa;
3252 int flags;
3253 int reserved;
3254 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3255 CXCursor);
3256} *CXCursorVisitorBlock;
3257
3258static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3259 CXClientData client_data) {
3260 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3261 return block->invoke(block, cursor, parent);
3262}
3263#endif
3264
3265
3266unsigned clang_visitChildrenWithBlock(CXCursor parent,
3267 CXCursorVisitorBlock block) {
3268 return clang_visitChildren(parent, visitWithBlock, block);
3269}
3270
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003271static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003272 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003273 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003274
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003275 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003276 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003277 if (const ObjCPropertyImplDecl *PropImpl =
3278 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003279 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003280 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003281
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003282 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003283 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003284 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003285
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003286 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003287 }
3288
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003289 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003290 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003291
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003292 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003293 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3294 // and returns different names. NamedDecl returns the class name and
3295 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003296 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003297
3298 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003299 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003300
3301 SmallString<1024> S;
3302 llvm::raw_svector_ostream os(S);
3303 ND->printName(os);
3304
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003305 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003306}
3307
3308CXString clang_getCursorSpelling(CXCursor C) {
3309 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003310 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003311
3312 if (clang_isReference(C.kind)) {
3313 switch (C.kind) {
3314 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003315 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003316 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003317 }
3318 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003319 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003320 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003321 }
3322 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003323 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003324 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003325 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003326 }
3327 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003328 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003329 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003330 }
3331 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003332 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003333 assert(Type && "Missing type decl");
3334
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003335 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003336 getAsString());
3337 }
3338 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003339 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003340 assert(Template && "Missing template decl");
3341
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003342 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003343 }
3344
3345 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003346 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003347 assert(NS && "Missing namespace decl");
3348
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003349 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003350 }
3351
3352 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003353 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003354 assert(Field && "Missing member decl");
3355
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003356 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003357 }
3358
3359 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003360 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003361 assert(Label && "Missing label");
3362
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003363 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003364 }
3365
3366 case CXCursor_OverloadedDeclRef: {
3367 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003368 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3369 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003370 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003371 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003372 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003373 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003374 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003375 OverloadedTemplateStorage *Ovl
3376 = Storage.get<OverloadedTemplateStorage*>();
3377 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003378 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003379 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 }
3381
3382 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003383 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003384 assert(Var && "Missing variable decl");
3385
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003386 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003387 }
3388
3389 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003390 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003391 }
3392 }
3393
3394 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003395 const Expr *E = getCursorExpr(C);
3396
3397 if (C.kind == CXCursor_ObjCStringLiteral ||
3398 C.kind == CXCursor_StringLiteral) {
3399 const StringLiteral *SLit;
3400 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3401 SLit = OSL->getString();
3402 } else {
3403 SLit = cast<StringLiteral>(E);
3404 }
3405 SmallString<256> Buf;
3406 llvm::raw_svector_ostream OS(Buf);
3407 SLit->outputString(OS);
3408 return cxstring::createDup(OS.str());
3409 }
3410
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003411 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003412 if (D)
3413 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003414 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003415 }
3416
3417 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003418 const Stmt *S = getCursorStmt(C);
3419 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003420 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003421
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003422 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003423 }
3424
3425 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003426 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003427 ->getNameStart());
3428
3429 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003430 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003431 ->getNameStart());
3432
3433 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003434 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003435
3436 if (clang_isDeclaration(C.kind))
3437 return getDeclSpelling(getCursorDecl(C));
3438
3439 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003440 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003441 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003442 }
3443
3444 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003445 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003446 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003447 }
3448
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003449 if (C.kind == CXCursor_PackedAttr) {
3450 return cxstring::createRef("packed");
3451 }
3452
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003453 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003454}
3455
3456CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3457 unsigned pieceIndex,
3458 unsigned options) {
3459 if (clang_Cursor_isNull(C))
3460 return clang_getNullRange();
3461
3462 ASTContext &Ctx = getCursorContext(C);
3463
3464 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003465 const Stmt *S = getCursorStmt(C);
3466 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003467 if (pieceIndex > 0)
3468 return clang_getNullRange();
3469 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3470 }
3471
3472 return clang_getNullRange();
3473 }
3474
3475 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003476 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003477 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3478 if (pieceIndex >= ME->getNumSelectorLocs())
3479 return clang_getNullRange();
3480 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3481 }
3482 }
3483
3484 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3485 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003486 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003487 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3488 if (pieceIndex >= MD->getNumSelectorLocs())
3489 return clang_getNullRange();
3490 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3491 }
3492 }
3493
3494 if (C.kind == CXCursor_ObjCCategoryDecl ||
3495 C.kind == CXCursor_ObjCCategoryImplDecl) {
3496 if (pieceIndex > 0)
3497 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003498 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003499 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3500 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003501 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003502 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3503 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3504 }
3505
3506 if (C.kind == CXCursor_ModuleImportDecl) {
3507 if (pieceIndex > 0)
3508 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003509 if (const ImportDecl *ImportD =
3510 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003511 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3512 if (!Locs.empty())
3513 return cxloc::translateSourceRange(Ctx,
3514 SourceRange(Locs.front(), Locs.back()));
3515 }
3516 return clang_getNullRange();
3517 }
3518
3519 // FIXME: A CXCursor_InclusionDirective should give the location of the
3520 // filename, but we don't keep track of this.
3521
3522 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3523 // but we don't keep track of this.
3524
3525 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3526 // but we don't keep track of this.
3527
3528 // Default handling, give the location of the cursor.
3529
3530 if (pieceIndex > 0)
3531 return clang_getNullRange();
3532
3533 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3534 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3535 return cxloc::translateSourceRange(Ctx, Loc);
3536}
3537
3538CXString clang_getCursorDisplayName(CXCursor C) {
3539 if (!clang_isDeclaration(C.kind))
3540 return clang_getCursorSpelling(C);
3541
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003542 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003543 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003544 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003545
3546 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003547 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003548 D = FunTmpl->getTemplatedDecl();
3549
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003550 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003551 SmallString<64> Str;
3552 llvm::raw_svector_ostream OS(Str);
3553 OS << *Function;
3554 if (Function->getPrimaryTemplate())
3555 OS << "<>";
3556 OS << "(";
3557 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3558 if (I)
3559 OS << ", ";
3560 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3561 }
3562
3563 if (Function->isVariadic()) {
3564 if (Function->getNumParams())
3565 OS << ", ";
3566 OS << "...";
3567 }
3568 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003569 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003570 }
3571
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003572 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003573 SmallString<64> Str;
3574 llvm::raw_svector_ostream OS(Str);
3575 OS << *ClassTemplate;
3576 OS << "<";
3577 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3578 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3579 if (I)
3580 OS << ", ";
3581
3582 NamedDecl *Param = Params->getParam(I);
3583 if (Param->getIdentifier()) {
3584 OS << Param->getIdentifier()->getName();
3585 continue;
3586 }
3587
3588 // There is no parameter name, which makes this tricky. Try to come up
3589 // with something useful that isn't too long.
3590 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3591 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3592 else if (NonTypeTemplateParmDecl *NTTP
3593 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3594 OS << NTTP->getType().getAsString(Policy);
3595 else
3596 OS << "template<...> class";
3597 }
3598
3599 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003600 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003601 }
3602
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003603 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003604 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3605 // If the type was explicitly written, use that.
3606 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003607 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003608
Benjamin Kramer9170e912013-02-22 15:46:01 +00003609 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003610 llvm::raw_svector_ostream OS(Str);
3611 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003612 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003613 ClassSpec->getTemplateArgs().data(),
3614 ClassSpec->getTemplateArgs().size(),
3615 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003616 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003617 }
3618
3619 return clang_getCursorSpelling(C);
3620}
3621
3622CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3623 switch (Kind) {
3624 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003625 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003626 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003627 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003628 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003629 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003630 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003631 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003632 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003633 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003635 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003637 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003641 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003643 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003645 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003647 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003651 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003653 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003655 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003659 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003663 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003665 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003673 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003752 case CXCursor_ObjCSelfExpr:
3753 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003870 case CXCursor_PackedAttr:
3871 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003872 case CXCursor_PureAttr:
3873 return cxstring::createRef("attribute(pure)");
3874 case CXCursor_ConstAttr:
3875 return cxstring::createRef("attribute(const)");
3876 case CXCursor_NoDuplicateAttr:
3877 return cxstring::createRef("attribute(noduplicate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003926 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003927 return cxstring::createRef("OMPParallelDirective");
3928 case CXCursor_OMPSimdDirective:
3929 return cxstring::createRef("OMPSimdDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 }
3931
3932 llvm_unreachable("Unhandled CXCursorKind");
3933}
3934
3935struct GetCursorData {
3936 SourceLocation TokenBeginLoc;
3937 bool PointsAtMacroArgExpansion;
3938 bool VisitedObjCPropertyImplDecl;
3939 SourceLocation VisitedDeclaratorDeclStartLoc;
3940 CXCursor &BestCursor;
3941
3942 GetCursorData(SourceManager &SM,
3943 SourceLocation tokenBegin, CXCursor &outputCursor)
3944 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3945 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3946 VisitedObjCPropertyImplDecl = false;
3947 }
3948};
3949
3950static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3951 CXCursor parent,
3952 CXClientData client_data) {
3953 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3954 CXCursor *BestCursor = &Data->BestCursor;
3955
3956 // If we point inside a macro argument we should provide info of what the
3957 // token is so use the actual cursor, don't replace it with a macro expansion
3958 // cursor.
3959 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3960 return CXChildVisit_Recurse;
3961
3962 if (clang_isDeclaration(cursor.kind)) {
3963 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003964 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003965 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3966 if (MD->isImplicit())
3967 return CXChildVisit_Break;
3968
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003969 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003970 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3971 // Check that when we have multiple @class references in the same line,
3972 // that later ones do not override the previous ones.
3973 // If we have:
3974 // @class Foo, Bar;
3975 // source ranges for both start at '@', so 'Bar' will end up overriding
3976 // 'Foo' even though the cursor location was at 'Foo'.
3977 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3978 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003979 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3981 if (PrevID != ID &&
3982 !PrevID->isThisDeclarationADefinition() &&
3983 !ID->isThisDeclarationADefinition())
3984 return CXChildVisit_Break;
3985 }
3986
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003987 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003988 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3989 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3990 // Check that when we have multiple declarators in the same line,
3991 // that later ones do not override the previous ones.
3992 // If we have:
3993 // int Foo, Bar;
3994 // source ranges for both start at 'int', so 'Bar' will end up overriding
3995 // 'Foo' even though the cursor location was at 'Foo'.
3996 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3997 return CXChildVisit_Break;
3998 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3999
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004000 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004001 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4002 (void)PropImp;
4003 // Check that when we have multiple @synthesize in the same line,
4004 // that later ones do not override the previous ones.
4005 // If we have:
4006 // @synthesize Foo, Bar;
4007 // source ranges for both start at '@', so 'Bar' will end up overriding
4008 // 'Foo' even though the cursor location was at 'Foo'.
4009 if (Data->VisitedObjCPropertyImplDecl)
4010 return CXChildVisit_Break;
4011 Data->VisitedObjCPropertyImplDecl = true;
4012 }
4013 }
4014
4015 if (clang_isExpression(cursor.kind) &&
4016 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004017 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004018 // Avoid having the cursor of an expression replace the declaration cursor
4019 // when the expression source range overlaps the declaration range.
4020 // This can happen for C++ constructor expressions whose range generally
4021 // include the variable declaration, e.g.:
4022 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4023 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4024 D->getLocation() == Data->TokenBeginLoc)
4025 return CXChildVisit_Break;
4026 }
4027 }
4028
4029 // If our current best cursor is the construction of a temporary object,
4030 // don't replace that cursor with a type reference, because we want
4031 // clang_getCursor() to point at the constructor.
4032 if (clang_isExpression(BestCursor->kind) &&
4033 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4034 cursor.kind == CXCursor_TypeRef) {
4035 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4036 // as having the actual point on the type reference.
4037 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4038 return CXChildVisit_Recurse;
4039 }
4040
4041 *BestCursor = cursor;
4042 return CXChildVisit_Recurse;
4043}
4044
4045CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004046 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004047 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004048 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004049 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004050
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004051 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004052 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4053
4054 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4055 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4056
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004057 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004058 CXFile SearchFile;
4059 unsigned SearchLine, SearchColumn;
4060 CXFile ResultFile;
4061 unsigned ResultLine, ResultColumn;
4062 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4063 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4064 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4065
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004066 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4067 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 &ResultColumn, 0);
4069 SearchFileName = clang_getFileName(SearchFile);
4070 ResultFileName = clang_getFileName(ResultFile);
4071 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4072 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004073 *Log << llvm::format("(%s:%d:%d) = %s",
4074 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4075 clang_getCString(KindSpelling))
4076 << llvm::format("(%s:%d:%d):%s%s",
4077 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4078 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004079 clang_disposeString(SearchFileName);
4080 clang_disposeString(ResultFileName);
4081 clang_disposeString(KindSpelling);
4082 clang_disposeString(USR);
4083
4084 CXCursor Definition = clang_getCursorDefinition(Result);
4085 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4086 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4087 CXString DefinitionKindSpelling
4088 = clang_getCursorKindSpelling(Definition.kind);
4089 CXFile DefinitionFile;
4090 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004091 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004092 &DefinitionLine, &DefinitionColumn, 0);
4093 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004094 *Log << llvm::format(" -> %s(%s:%d:%d)",
4095 clang_getCString(DefinitionKindSpelling),
4096 clang_getCString(DefinitionFileName),
4097 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004098 clang_disposeString(DefinitionFileName);
4099 clang_disposeString(DefinitionKindSpelling);
4100 }
4101 }
4102
4103 return Result;
4104}
4105
4106CXCursor clang_getNullCursor(void) {
4107 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4108}
4109
4110unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004111 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4112 // can't set consistently. For example, when visiting a DeclStmt we will set
4113 // it but we don't set it on the result of clang_getCursorDefinition for
4114 // a reference of the same declaration.
4115 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4116 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4117 // to provide that kind of info.
4118 if (clang_isDeclaration(X.kind))
4119 X.data[1] = 0;
4120 if (clang_isDeclaration(Y.kind))
4121 Y.data[1] = 0;
4122
Guy Benyei11169dd2012-12-18 14:30:41 +00004123 return X == Y;
4124}
4125
4126unsigned clang_hashCursor(CXCursor C) {
4127 unsigned Index = 0;
4128 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4129 Index = 1;
4130
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004131 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004132 std::make_pair(C.kind, C.data[Index]));
4133}
4134
4135unsigned clang_isInvalid(enum CXCursorKind K) {
4136 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4137}
4138
4139unsigned clang_isDeclaration(enum CXCursorKind K) {
4140 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4141 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4142}
4143
4144unsigned clang_isReference(enum CXCursorKind K) {
4145 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4146}
4147
4148unsigned clang_isExpression(enum CXCursorKind K) {
4149 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4150}
4151
4152unsigned clang_isStatement(enum CXCursorKind K) {
4153 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4154}
4155
4156unsigned clang_isAttribute(enum CXCursorKind K) {
4157 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4158}
4159
4160unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4161 return K == CXCursor_TranslationUnit;
4162}
4163
4164unsigned clang_isPreprocessing(enum CXCursorKind K) {
4165 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4166}
4167
4168unsigned clang_isUnexposed(enum CXCursorKind K) {
4169 switch (K) {
4170 case CXCursor_UnexposedDecl:
4171 case CXCursor_UnexposedExpr:
4172 case CXCursor_UnexposedStmt:
4173 case CXCursor_UnexposedAttr:
4174 return true;
4175 default:
4176 return false;
4177 }
4178}
4179
4180CXCursorKind clang_getCursorKind(CXCursor C) {
4181 return C.kind;
4182}
4183
4184CXSourceLocation clang_getCursorLocation(CXCursor C) {
4185 if (clang_isReference(C.kind)) {
4186 switch (C.kind) {
4187 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004188 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004189 = getCursorObjCSuperClassRef(C);
4190 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4191 }
4192
4193 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004194 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004195 = getCursorObjCProtocolRef(C);
4196 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4197 }
4198
4199 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004200 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004201 = getCursorObjCClassRef(C);
4202 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4203 }
4204
4205 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004206 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004207 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4208 }
4209
4210 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004211 std::pair<const TemplateDecl *, SourceLocation> P =
4212 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004213 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4214 }
4215
4216 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004217 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004218 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4219 }
4220
4221 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004222 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004223 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4224 }
4225
4226 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004227 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004228 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4229 }
4230
4231 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004232 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004233 if (!BaseSpec)
4234 return clang_getNullLocation();
4235
4236 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4237 return cxloc::translateSourceLocation(getCursorContext(C),
4238 TSInfo->getTypeLoc().getBeginLoc());
4239
4240 return cxloc::translateSourceLocation(getCursorContext(C),
4241 BaseSpec->getLocStart());
4242 }
4243
4244 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004245 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004246 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4247 }
4248
4249 case CXCursor_OverloadedDeclRef:
4250 return cxloc::translateSourceLocation(getCursorContext(C),
4251 getCursorOverloadedDeclRef(C).second);
4252
4253 default:
4254 // FIXME: Need a way to enumerate all non-reference cases.
4255 llvm_unreachable("Missed a reference kind");
4256 }
4257 }
4258
4259 if (clang_isExpression(C.kind))
4260 return cxloc::translateSourceLocation(getCursorContext(C),
4261 getLocationFromExpr(getCursorExpr(C)));
4262
4263 if (clang_isStatement(C.kind))
4264 return cxloc::translateSourceLocation(getCursorContext(C),
4265 getCursorStmt(C)->getLocStart());
4266
4267 if (C.kind == CXCursor_PreprocessingDirective) {
4268 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4269 return cxloc::translateSourceLocation(getCursorContext(C), L);
4270 }
4271
4272 if (C.kind == CXCursor_MacroExpansion) {
4273 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004274 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004275 return cxloc::translateSourceLocation(getCursorContext(C), L);
4276 }
4277
4278 if (C.kind == CXCursor_MacroDefinition) {
4279 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4280 return cxloc::translateSourceLocation(getCursorContext(C), L);
4281 }
4282
4283 if (C.kind == CXCursor_InclusionDirective) {
4284 SourceLocation L
4285 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4286 return cxloc::translateSourceLocation(getCursorContext(C), L);
4287 }
4288
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004289 if (clang_isAttribute(C.kind)) {
4290 SourceLocation L
4291 = cxcursor::getCursorAttr(C)->getLocation();
4292 return cxloc::translateSourceLocation(getCursorContext(C), L);
4293 }
4294
Guy Benyei11169dd2012-12-18 14:30:41 +00004295 if (!clang_isDeclaration(C.kind))
4296 return clang_getNullLocation();
4297
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004298 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004299 if (!D)
4300 return clang_getNullLocation();
4301
4302 SourceLocation Loc = D->getLocation();
4303 // FIXME: Multiple variables declared in a single declaration
4304 // currently lack the information needed to correctly determine their
4305 // ranges when accounting for the type-specifier. We use context
4306 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4307 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004308 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004309 if (!cxcursor::isFirstInDeclGroup(C))
4310 Loc = VD->getLocation();
4311 }
4312
4313 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004314 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004315 Loc = MD->getSelectorStartLoc();
4316
4317 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4318}
4319
4320} // end extern "C"
4321
4322CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4323 assert(TU);
4324
4325 // Guard against an invalid SourceLocation, or we may assert in one
4326 // of the following calls.
4327 if (SLoc.isInvalid())
4328 return clang_getNullCursor();
4329
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004330 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004331
4332 // Translate the given source location to make it point at the beginning of
4333 // the token under the cursor.
4334 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4335 CXXUnit->getASTContext().getLangOpts());
4336
4337 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4338 if (SLoc.isValid()) {
4339 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4340 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4341 /*VisitPreprocessorLast=*/true,
4342 /*VisitIncludedEntities=*/false,
4343 SourceLocation(SLoc));
4344 CursorVis.visitFileRegion();
4345 }
4346
4347 return Result;
4348}
4349
4350static SourceRange getRawCursorExtent(CXCursor C) {
4351 if (clang_isReference(C.kind)) {
4352 switch (C.kind) {
4353 case CXCursor_ObjCSuperClassRef:
4354 return getCursorObjCSuperClassRef(C).second;
4355
4356 case CXCursor_ObjCProtocolRef:
4357 return getCursorObjCProtocolRef(C).second;
4358
4359 case CXCursor_ObjCClassRef:
4360 return getCursorObjCClassRef(C).second;
4361
4362 case CXCursor_TypeRef:
4363 return getCursorTypeRef(C).second;
4364
4365 case CXCursor_TemplateRef:
4366 return getCursorTemplateRef(C).second;
4367
4368 case CXCursor_NamespaceRef:
4369 return getCursorNamespaceRef(C).second;
4370
4371 case CXCursor_MemberRef:
4372 return getCursorMemberRef(C).second;
4373
4374 case CXCursor_CXXBaseSpecifier:
4375 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4376
4377 case CXCursor_LabelRef:
4378 return getCursorLabelRef(C).second;
4379
4380 case CXCursor_OverloadedDeclRef:
4381 return getCursorOverloadedDeclRef(C).second;
4382
4383 case CXCursor_VariableRef:
4384 return getCursorVariableRef(C).second;
4385
4386 default:
4387 // FIXME: Need a way to enumerate all non-reference cases.
4388 llvm_unreachable("Missed a reference kind");
4389 }
4390 }
4391
4392 if (clang_isExpression(C.kind))
4393 return getCursorExpr(C)->getSourceRange();
4394
4395 if (clang_isStatement(C.kind))
4396 return getCursorStmt(C)->getSourceRange();
4397
4398 if (clang_isAttribute(C.kind))
4399 return getCursorAttr(C)->getRange();
4400
4401 if (C.kind == CXCursor_PreprocessingDirective)
4402 return cxcursor::getCursorPreprocessingDirective(C);
4403
4404 if (C.kind == CXCursor_MacroExpansion) {
4405 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004406 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004407 return TU->mapRangeFromPreamble(Range);
4408 }
4409
4410 if (C.kind == CXCursor_MacroDefinition) {
4411 ASTUnit *TU = getCursorASTUnit(C);
4412 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4413 return TU->mapRangeFromPreamble(Range);
4414 }
4415
4416 if (C.kind == CXCursor_InclusionDirective) {
4417 ASTUnit *TU = getCursorASTUnit(C);
4418 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4419 return TU->mapRangeFromPreamble(Range);
4420 }
4421
4422 if (C.kind == CXCursor_TranslationUnit) {
4423 ASTUnit *TU = getCursorASTUnit(C);
4424 FileID MainID = TU->getSourceManager().getMainFileID();
4425 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4426 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4427 return SourceRange(Start, End);
4428 }
4429
4430 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004431 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004432 if (!D)
4433 return SourceRange();
4434
4435 SourceRange R = D->getSourceRange();
4436 // FIXME: Multiple variables declared in a single declaration
4437 // currently lack the information needed to correctly determine their
4438 // ranges when accounting for the type-specifier. We use context
4439 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4440 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004441 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004442 if (!cxcursor::isFirstInDeclGroup(C))
4443 R.setBegin(VD->getLocation());
4444 }
4445 return R;
4446 }
4447 return SourceRange();
4448}
4449
4450/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4451/// the decl-specifier-seq for declarations.
4452static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4453 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004454 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004455 if (!D)
4456 return SourceRange();
4457
4458 SourceRange R = D->getSourceRange();
4459
4460 // Adjust the start of the location for declarations preceded by
4461 // declaration specifiers.
4462 SourceLocation StartLoc;
4463 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4464 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4465 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004466 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004467 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4468 StartLoc = TI->getTypeLoc().getLocStart();
4469 }
4470
4471 if (StartLoc.isValid() && R.getBegin().isValid() &&
4472 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4473 R.setBegin(StartLoc);
4474
4475 // FIXME: Multiple variables declared in a single declaration
4476 // currently lack the information needed to correctly determine their
4477 // ranges when accounting for the type-specifier. We use context
4478 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4479 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004480 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004481 if (!cxcursor::isFirstInDeclGroup(C))
4482 R.setBegin(VD->getLocation());
4483 }
4484
4485 return R;
4486 }
4487
4488 return getRawCursorExtent(C);
4489}
4490
4491extern "C" {
4492
4493CXSourceRange clang_getCursorExtent(CXCursor C) {
4494 SourceRange R = getRawCursorExtent(C);
4495 if (R.isInvalid())
4496 return clang_getNullRange();
4497
4498 return cxloc::translateSourceRange(getCursorContext(C), R);
4499}
4500
4501CXCursor clang_getCursorReferenced(CXCursor C) {
4502 if (clang_isInvalid(C.kind))
4503 return clang_getNullCursor();
4504
4505 CXTranslationUnit tu = getCursorTU(C);
4506 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004507 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004508 if (!D)
4509 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004510 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004511 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004512 if (const ObjCPropertyImplDecl *PropImpl =
4513 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004514 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4515 return MakeCXCursor(Property, tu);
4516
4517 return C;
4518 }
4519
4520 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004521 const Expr *E = getCursorExpr(C);
4522 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004523 if (D) {
4524 CXCursor declCursor = MakeCXCursor(D, tu);
4525 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4526 declCursor);
4527 return declCursor;
4528 }
4529
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004530 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004531 return MakeCursorOverloadedDeclRef(Ovl, tu);
4532
4533 return clang_getNullCursor();
4534 }
4535
4536 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004537 const Stmt *S = getCursorStmt(C);
4538 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004539 if (LabelDecl *label = Goto->getLabel())
4540 if (LabelStmt *labelS = label->getStmt())
4541 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4542
4543 return clang_getNullCursor();
4544 }
4545
4546 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004547 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004548 return MakeMacroDefinitionCursor(Def, tu);
4549 }
4550
4551 if (!clang_isReference(C.kind))
4552 return clang_getNullCursor();
4553
4554 switch (C.kind) {
4555 case CXCursor_ObjCSuperClassRef:
4556 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4557
4558 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004559 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4560 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 return MakeCXCursor(Def, tu);
4562
4563 return MakeCXCursor(Prot, tu);
4564 }
4565
4566 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004567 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4568 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004569 return MakeCXCursor(Def, tu);
4570
4571 return MakeCXCursor(Class, tu);
4572 }
4573
4574 case CXCursor_TypeRef:
4575 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4576
4577 case CXCursor_TemplateRef:
4578 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4579
4580 case CXCursor_NamespaceRef:
4581 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4582
4583 case CXCursor_MemberRef:
4584 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4585
4586 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004587 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004588 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4589 tu ));
4590 }
4591
4592 case CXCursor_LabelRef:
4593 // FIXME: We end up faking the "parent" declaration here because we
4594 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004595 return MakeCXCursor(getCursorLabelRef(C).first,
4596 cxtu::getASTUnit(tu)->getASTContext()
4597 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004598 tu);
4599
4600 case CXCursor_OverloadedDeclRef:
4601 return C;
4602
4603 case CXCursor_VariableRef:
4604 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4605
4606 default:
4607 // We would prefer to enumerate all non-reference cursor kinds here.
4608 llvm_unreachable("Unhandled reference cursor kind");
4609 }
4610}
4611
4612CXCursor clang_getCursorDefinition(CXCursor C) {
4613 if (clang_isInvalid(C.kind))
4614 return clang_getNullCursor();
4615
4616 CXTranslationUnit TU = getCursorTU(C);
4617
4618 bool WasReference = false;
4619 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4620 C = clang_getCursorReferenced(C);
4621 WasReference = true;
4622 }
4623
4624 if (C.kind == CXCursor_MacroExpansion)
4625 return clang_getCursorReferenced(C);
4626
4627 if (!clang_isDeclaration(C.kind))
4628 return clang_getNullCursor();
4629
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004630 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004631 if (!D)
4632 return clang_getNullCursor();
4633
4634 switch (D->getKind()) {
4635 // Declaration kinds that don't really separate the notions of
4636 // declaration and definition.
4637 case Decl::Namespace:
4638 case Decl::Typedef:
4639 case Decl::TypeAlias:
4640 case Decl::TypeAliasTemplate:
4641 case Decl::TemplateTypeParm:
4642 case Decl::EnumConstant:
4643 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004644 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004645 case Decl::IndirectField:
4646 case Decl::ObjCIvar:
4647 case Decl::ObjCAtDefsField:
4648 case Decl::ImplicitParam:
4649 case Decl::ParmVar:
4650 case Decl::NonTypeTemplateParm:
4651 case Decl::TemplateTemplateParm:
4652 case Decl::ObjCCategoryImpl:
4653 case Decl::ObjCImplementation:
4654 case Decl::AccessSpec:
4655 case Decl::LinkageSpec:
4656 case Decl::ObjCPropertyImpl:
4657 case Decl::FileScopeAsm:
4658 case Decl::StaticAssert:
4659 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004660 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 case Decl::Label: // FIXME: Is this right??
4662 case Decl::ClassScopeFunctionSpecialization:
4663 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004664 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004665 return C;
4666
4667 // Declaration kinds that don't make any sense here, but are
4668 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004669 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004670 case Decl::TranslationUnit:
4671 break;
4672
4673 // Declaration kinds for which the definition is not resolvable.
4674 case Decl::UnresolvedUsingTypename:
4675 case Decl::UnresolvedUsingValue:
4676 break;
4677
4678 case Decl::UsingDirective:
4679 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4680 TU);
4681
4682 case Decl::NamespaceAlias:
4683 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4684
4685 case Decl::Enum:
4686 case Decl::Record:
4687 case Decl::CXXRecord:
4688 case Decl::ClassTemplateSpecialization:
4689 case Decl::ClassTemplatePartialSpecialization:
4690 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4691 return MakeCXCursor(Def, TU);
4692 return clang_getNullCursor();
4693
4694 case Decl::Function:
4695 case Decl::CXXMethod:
4696 case Decl::CXXConstructor:
4697 case Decl::CXXDestructor:
4698 case Decl::CXXConversion: {
4699 const FunctionDecl *Def = 0;
4700 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004701 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004702 return clang_getNullCursor();
4703 }
4704
Larisse Voufo39a1e502013-08-06 01:03:05 +00004705 case Decl::Var:
4706 case Decl::VarTemplateSpecialization:
4707 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004708 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004709 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004710 return MakeCXCursor(Def, TU);
4711 return clang_getNullCursor();
4712 }
4713
4714 case Decl::FunctionTemplate: {
4715 const FunctionDecl *Def = 0;
4716 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4717 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4718 return clang_getNullCursor();
4719 }
4720
4721 case Decl::ClassTemplate: {
4722 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4723 ->getDefinition())
4724 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4725 TU);
4726 return clang_getNullCursor();
4727 }
4728
Larisse Voufo39a1e502013-08-06 01:03:05 +00004729 case Decl::VarTemplate: {
4730 if (VarDecl *Def =
4731 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4732 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4733 return clang_getNullCursor();
4734 }
4735
Guy Benyei11169dd2012-12-18 14:30:41 +00004736 case Decl::Using:
4737 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4738 D->getLocation(), TU);
4739
4740 case Decl::UsingShadow:
4741 return clang_getCursorDefinition(
4742 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4743 TU));
4744
4745 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004746 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004747 if (Method->isThisDeclarationADefinition())
4748 return C;
4749
4750 // Dig out the method definition in the associated
4751 // @implementation, if we have it.
4752 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004753 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004754 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4755 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4756 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4757 Method->isInstanceMethod()))
4758 if (Def->isThisDeclarationADefinition())
4759 return MakeCXCursor(Def, TU);
4760
4761 return clang_getNullCursor();
4762 }
4763
4764 case Decl::ObjCCategory:
4765 if (ObjCCategoryImplDecl *Impl
4766 = cast<ObjCCategoryDecl>(D)->getImplementation())
4767 return MakeCXCursor(Impl, TU);
4768 return clang_getNullCursor();
4769
4770 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004771 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004772 return MakeCXCursor(Def, TU);
4773 return clang_getNullCursor();
4774
4775 case Decl::ObjCInterface: {
4776 // There are two notions of a "definition" for an Objective-C
4777 // class: the interface and its implementation. When we resolved a
4778 // reference to an Objective-C class, produce the @interface as
4779 // the definition; when we were provided with the interface,
4780 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004781 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004782 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004783 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004784 return MakeCXCursor(Def, TU);
4785 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4786 return MakeCXCursor(Impl, TU);
4787 return clang_getNullCursor();
4788 }
4789
4790 case Decl::ObjCProperty:
4791 // FIXME: We don't really know where to find the
4792 // ObjCPropertyImplDecls that implement this property.
4793 return clang_getNullCursor();
4794
4795 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004796 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004797 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004798 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004799 return MakeCXCursor(Def, TU);
4800
4801 return clang_getNullCursor();
4802
4803 case Decl::Friend:
4804 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4805 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4806 return clang_getNullCursor();
4807
4808 case Decl::FriendTemplate:
4809 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4810 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4811 return clang_getNullCursor();
4812 }
4813
4814 return clang_getNullCursor();
4815}
4816
4817unsigned clang_isCursorDefinition(CXCursor C) {
4818 if (!clang_isDeclaration(C.kind))
4819 return 0;
4820
4821 return clang_getCursorDefinition(C) == C;
4822}
4823
4824CXCursor clang_getCanonicalCursor(CXCursor C) {
4825 if (!clang_isDeclaration(C.kind))
4826 return C;
4827
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004828 if (const Decl *D = getCursorDecl(C)) {
4829 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004830 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4831 return MakeCXCursor(CatD, getCursorTU(C));
4832
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004833 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4834 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004835 return MakeCXCursor(IFD, getCursorTU(C));
4836
4837 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4838 }
4839
4840 return C;
4841}
4842
4843int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4844 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4845}
4846
4847unsigned clang_getNumOverloadedDecls(CXCursor C) {
4848 if (C.kind != CXCursor_OverloadedDeclRef)
4849 return 0;
4850
4851 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004852 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004853 return E->getNumDecls();
4854
4855 if (OverloadedTemplateStorage *S
4856 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4857 return S->size();
4858
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004859 const Decl *D = Storage.get<const Decl *>();
4860 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004861 return Using->shadow_size();
4862
4863 return 0;
4864}
4865
4866CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4867 if (cursor.kind != CXCursor_OverloadedDeclRef)
4868 return clang_getNullCursor();
4869
4870 if (index >= clang_getNumOverloadedDecls(cursor))
4871 return clang_getNullCursor();
4872
4873 CXTranslationUnit TU = getCursorTU(cursor);
4874 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004875 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004876 return MakeCXCursor(E->decls_begin()[index], TU);
4877
4878 if (OverloadedTemplateStorage *S
4879 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4880 return MakeCXCursor(S->begin()[index], TU);
4881
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004882 const Decl *D = Storage.get<const Decl *>();
4883 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004884 // FIXME: This is, unfortunately, linear time.
4885 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4886 std::advance(Pos, index);
4887 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4888 }
4889
4890 return clang_getNullCursor();
4891}
4892
4893void clang_getDefinitionSpellingAndExtent(CXCursor C,
4894 const char **startBuf,
4895 const char **endBuf,
4896 unsigned *startLine,
4897 unsigned *startColumn,
4898 unsigned *endLine,
4899 unsigned *endColumn) {
4900 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004901 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004902 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4903
4904 SourceManager &SM = FD->getASTContext().getSourceManager();
4905 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4906 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4907 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4908 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4909 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4910 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4911}
4912
4913
4914CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4915 unsigned PieceIndex) {
4916 RefNamePieces Pieces;
4917
4918 switch (C.kind) {
4919 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004920 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004921 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4922 E->getQualifierLoc().getSourceRange());
4923 break;
4924
4925 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004926 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004927 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4928 E->getQualifierLoc().getSourceRange(),
4929 E->getOptionalExplicitTemplateArgs());
4930 break;
4931
4932 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004933 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004934 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004935 const Expr *Callee = OCE->getCallee();
4936 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004937 Callee = ICE->getSubExpr();
4938
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004939 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004940 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4941 DRE->getQualifierLoc().getSourceRange());
4942 }
4943 break;
4944
4945 default:
4946 break;
4947 }
4948
4949 if (Pieces.empty()) {
4950 if (PieceIndex == 0)
4951 return clang_getCursorExtent(C);
4952 } else if (PieceIndex < Pieces.size()) {
4953 SourceRange R = Pieces[PieceIndex];
4954 if (R.isValid())
4955 return cxloc::translateSourceRange(getCursorContext(C), R);
4956 }
4957
4958 return clang_getNullRange();
4959}
4960
4961void clang_enableStackTraces(void) {
4962 llvm::sys::PrintStackTraceOnErrorSignal();
4963}
4964
4965void clang_executeOnThread(void (*fn)(void*), void *user_data,
4966 unsigned stack_size) {
4967 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4968}
4969
4970} // end: extern "C"
4971
4972//===----------------------------------------------------------------------===//
4973// Token-based Operations.
4974//===----------------------------------------------------------------------===//
4975
4976/* CXToken layout:
4977 * int_data[0]: a CXTokenKind
4978 * int_data[1]: starting token location
4979 * int_data[2]: token length
4980 * int_data[3]: reserved
4981 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4982 * otherwise unused.
4983 */
4984extern "C" {
4985
4986CXTokenKind clang_getTokenKind(CXToken CXTok) {
4987 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4988}
4989
4990CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4991 switch (clang_getTokenKind(CXTok)) {
4992 case CXToken_Identifier:
4993 case CXToken_Keyword:
4994 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004995 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004996 ->getNameStart());
4997
4998 case CXToken_Literal: {
4999 // We have stashed the starting pointer in the ptr_data field. Use it.
5000 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005001 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005002 }
5003
5004 case CXToken_Punctuation:
5005 case CXToken_Comment:
5006 break;
5007 }
5008
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005009 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005010 LOG_BAD_TU(TU);
5011 return cxstring::createEmpty();
5012 }
5013
Guy Benyei11169dd2012-12-18 14:30:41 +00005014 // We have to find the starting buffer pointer the hard way, by
5015 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005016 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005017 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005018 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005019
5020 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5021 std::pair<FileID, unsigned> LocInfo
5022 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5023 bool Invalid = false;
5024 StringRef Buffer
5025 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5026 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005027 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005028
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005029 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005030}
5031
5032CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005033 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005034 LOG_BAD_TU(TU);
5035 return clang_getNullLocation();
5036 }
5037
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005038 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005039 if (!CXXUnit)
5040 return clang_getNullLocation();
5041
5042 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5043 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5044}
5045
5046CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005047 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005048 LOG_BAD_TU(TU);
5049 return clang_getNullRange();
5050 }
5051
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005052 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005053 if (!CXXUnit)
5054 return clang_getNullRange();
5055
5056 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5057 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5058}
5059
5060static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5061 SmallVectorImpl<CXToken> &CXTokens) {
5062 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5063 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005064 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005065 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005066 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005067
5068 // Cannot tokenize across files.
5069 if (BeginLocInfo.first != EndLocInfo.first)
5070 return;
5071
5072 // Create a lexer
5073 bool Invalid = false;
5074 StringRef Buffer
5075 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5076 if (Invalid)
5077 return;
5078
5079 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5080 CXXUnit->getASTContext().getLangOpts(),
5081 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5082 Lex.SetCommentRetentionState(true);
5083
5084 // Lex tokens until we hit the end of the range.
5085 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5086 Token Tok;
5087 bool previousWasAt = false;
5088 do {
5089 // Lex the next token
5090 Lex.LexFromRawLexer(Tok);
5091 if (Tok.is(tok::eof))
5092 break;
5093
5094 // Initialize the CXToken.
5095 CXToken CXTok;
5096
5097 // - Common fields
5098 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5099 CXTok.int_data[2] = Tok.getLength();
5100 CXTok.int_data[3] = 0;
5101
5102 // - Kind-specific fields
5103 if (Tok.isLiteral()) {
5104 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005105 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005106 } else if (Tok.is(tok::raw_identifier)) {
5107 // Lookup the identifier to determine whether we have a keyword.
5108 IdentifierInfo *II
5109 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5110
5111 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5112 CXTok.int_data[0] = CXToken_Keyword;
5113 }
5114 else {
5115 CXTok.int_data[0] = Tok.is(tok::identifier)
5116 ? CXToken_Identifier
5117 : CXToken_Keyword;
5118 }
5119 CXTok.ptr_data = II;
5120 } else if (Tok.is(tok::comment)) {
5121 CXTok.int_data[0] = CXToken_Comment;
5122 CXTok.ptr_data = 0;
5123 } else {
5124 CXTok.int_data[0] = CXToken_Punctuation;
5125 CXTok.ptr_data = 0;
5126 }
5127 CXTokens.push_back(CXTok);
5128 previousWasAt = Tok.is(tok::at);
5129 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5130}
5131
5132void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5133 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005134 LOG_FUNC_SECTION {
5135 *Log << TU << ' ' << Range;
5136 }
5137
Guy Benyei11169dd2012-12-18 14:30:41 +00005138 if (Tokens)
5139 *Tokens = 0;
5140 if (NumTokens)
5141 *NumTokens = 0;
5142
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005143 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005144 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005145 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005146 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005147
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005148 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005149 if (!CXXUnit || !Tokens || !NumTokens)
5150 return;
5151
5152 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5153
5154 SourceRange R = cxloc::translateCXSourceRange(Range);
5155 if (R.isInvalid())
5156 return;
5157
5158 SmallVector<CXToken, 32> CXTokens;
5159 getTokens(CXXUnit, R, CXTokens);
5160
5161 if (CXTokens.empty())
5162 return;
5163
5164 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5165 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5166 *NumTokens = CXTokens.size();
5167}
5168
5169void clang_disposeTokens(CXTranslationUnit TU,
5170 CXToken *Tokens, unsigned NumTokens) {
5171 free(Tokens);
5172}
5173
5174} // end: extern "C"
5175
5176//===----------------------------------------------------------------------===//
5177// Token annotation APIs.
5178//===----------------------------------------------------------------------===//
5179
Guy Benyei11169dd2012-12-18 14:30:41 +00005180static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5181 CXCursor parent,
5182 CXClientData client_data);
5183static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5184 CXClientData client_data);
5185
5186namespace {
5187class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005188 CXToken *Tokens;
5189 CXCursor *Cursors;
5190 unsigned NumTokens;
5191 unsigned TokIdx;
5192 unsigned PreprocessingTokIdx;
5193 CursorVisitor AnnotateVis;
5194 SourceManager &SrcMgr;
5195 bool HasContextSensitiveKeywords;
5196
5197 struct PostChildrenInfo {
5198 CXCursor Cursor;
5199 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005200 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005201 unsigned BeforeChildrenTokenIdx;
5202 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005203 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005204
5205 CXToken &getTok(unsigned Idx) {
5206 assert(Idx < NumTokens);
5207 return Tokens[Idx];
5208 }
5209 const CXToken &getTok(unsigned Idx) const {
5210 assert(Idx < NumTokens);
5211 return Tokens[Idx];
5212 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005213 bool MoreTokens() const { return TokIdx < NumTokens; }
5214 unsigned NextToken() const { return TokIdx; }
5215 void AdvanceToken() { ++TokIdx; }
5216 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005217 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005218 }
5219 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005220 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005221 }
5222 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005223 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005224 }
5225
5226 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005227 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 SourceRange);
5229
5230public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005231 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005232 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005233 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005234 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005235 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005236 AnnotateTokensVisitor, this,
5237 /*VisitPreprocessorLast=*/true,
5238 /*VisitIncludedEntities=*/false,
5239 RegionOfInterest,
5240 /*VisitDeclsOnly=*/false,
5241 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005242 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005243 HasContextSensitiveKeywords(false) { }
5244
5245 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5246 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5247 bool postVisitChildren(CXCursor cursor);
5248 void AnnotateTokens();
5249
5250 /// \brief Determine whether the annotator saw any cursors that have
5251 /// context-sensitive keywords.
5252 bool hasContextSensitiveKeywords() const {
5253 return HasContextSensitiveKeywords;
5254 }
5255
5256 ~AnnotateTokensWorker() {
5257 assert(PostChildrenInfos.empty());
5258 }
5259};
5260}
5261
5262void AnnotateTokensWorker::AnnotateTokens() {
5263 // Walk the AST within the region of interest, annotating tokens
5264 // along the way.
5265 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005266}
Guy Benyei11169dd2012-12-18 14:30:41 +00005267
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005268static inline void updateCursorAnnotation(CXCursor &Cursor,
5269 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005270 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005271 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005272 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005273}
5274
5275/// \brief It annotates and advances tokens with a cursor until the comparison
5276//// between the cursor location and the source range is the same as
5277/// \arg compResult.
5278///
5279/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5280/// Pass RangeOverlap to annotate tokens inside a range.
5281void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5282 RangeComparisonResult compResult,
5283 SourceRange range) {
5284 while (MoreTokens()) {
5285 const unsigned I = NextToken();
5286 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005287 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5288 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005289
5290 SourceLocation TokLoc = GetTokenLoc(I);
5291 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005292 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005293 AdvanceToken();
5294 continue;
5295 }
5296 break;
5297 }
5298}
5299
5300/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005301/// \returns true if it advanced beyond all macro tokens, false otherwise.
5302bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005303 CXCursor updateC,
5304 RangeComparisonResult compResult,
5305 SourceRange range) {
5306 assert(MoreTokens());
5307 assert(isFunctionMacroToken(NextToken()) &&
5308 "Should be called only for macro arg tokens");
5309
5310 // This works differently than annotateAndAdvanceTokens; because expanded
5311 // macro arguments can have arbitrary translation-unit source order, we do not
5312 // advance the token index one by one until a token fails the range test.
5313 // We only advance once past all of the macro arg tokens if all of them
5314 // pass the range test. If one of them fails we keep the token index pointing
5315 // at the start of the macro arg tokens so that the failing token will be
5316 // annotated by a subsequent annotation try.
5317
5318 bool atLeastOneCompFail = false;
5319
5320 unsigned I = NextToken();
5321 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5322 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5323 if (TokLoc.isFileID())
5324 continue; // not macro arg token, it's parens or comma.
5325 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5326 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5327 Cursors[I] = updateC;
5328 } else
5329 atLeastOneCompFail = true;
5330 }
5331
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005332 if (atLeastOneCompFail)
5333 return false;
5334
5335 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5336 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005337}
5338
5339enum CXChildVisitResult
5340AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005341 SourceRange cursorRange = getRawCursorExtent(cursor);
5342 if (cursorRange.isInvalid())
5343 return CXChildVisit_Recurse;
5344
5345 if (!HasContextSensitiveKeywords) {
5346 // Objective-C properties can have context-sensitive keywords.
5347 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005348 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005349 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5350 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5351 }
5352 // Objective-C methods can have context-sensitive keywords.
5353 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5354 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005355 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005356 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5357 if (Method->getObjCDeclQualifier())
5358 HasContextSensitiveKeywords = true;
5359 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005360 for (const auto *P : Method->params()) {
5361 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005362 HasContextSensitiveKeywords = true;
5363 break;
5364 }
5365 }
5366 }
5367 }
5368 }
5369 // C++ methods can have context-sensitive keywords.
5370 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005371 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005372 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5373 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5374 HasContextSensitiveKeywords = true;
5375 }
5376 }
5377 // C++ classes can have context-sensitive keywords.
5378 else if (cursor.kind == CXCursor_StructDecl ||
5379 cursor.kind == CXCursor_ClassDecl ||
5380 cursor.kind == CXCursor_ClassTemplate ||
5381 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005382 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005383 if (D->hasAttr<FinalAttr>())
5384 HasContextSensitiveKeywords = true;
5385 }
5386 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005387
5388 // Don't override a property annotation with its getter/setter method.
5389 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5390 parent.kind == CXCursor_ObjCPropertyDecl)
5391 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005392
5393 if (clang_isPreprocessing(cursor.kind)) {
5394 // Items in the preprocessing record are kept separate from items in
5395 // declarations, so we keep a separate token index.
5396 unsigned SavedTokIdx = TokIdx;
5397 TokIdx = PreprocessingTokIdx;
5398
5399 // Skip tokens up until we catch up to the beginning of the preprocessing
5400 // entry.
5401 while (MoreTokens()) {
5402 const unsigned I = NextToken();
5403 SourceLocation TokLoc = GetTokenLoc(I);
5404 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5405 case RangeBefore:
5406 AdvanceToken();
5407 continue;
5408 case RangeAfter:
5409 case RangeOverlap:
5410 break;
5411 }
5412 break;
5413 }
5414
5415 // Look at all of the tokens within this range.
5416 while (MoreTokens()) {
5417 const unsigned I = NextToken();
5418 SourceLocation TokLoc = GetTokenLoc(I);
5419 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5420 case RangeBefore:
5421 llvm_unreachable("Infeasible");
5422 case RangeAfter:
5423 break;
5424 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005425 // For macro expansions, just note where the beginning of the macro
5426 // expansion occurs.
5427 if (cursor.kind == CXCursor_MacroExpansion) {
5428 if (TokLoc == cursorRange.getBegin())
5429 Cursors[I] = cursor;
5430 AdvanceToken();
5431 break;
5432 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005433 // We may have already annotated macro names inside macro definitions.
5434 if (Cursors[I].kind != CXCursor_MacroExpansion)
5435 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005436 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005437 continue;
5438 }
5439 break;
5440 }
5441
5442 // Save the preprocessing token index; restore the non-preprocessing
5443 // token index.
5444 PreprocessingTokIdx = TokIdx;
5445 TokIdx = SavedTokIdx;
5446 return CXChildVisit_Recurse;
5447 }
5448
5449 if (cursorRange.isInvalid())
5450 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005451
5452 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005453 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005454 const enum CXCursorKind K = clang_getCursorKind(parent);
5455 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005456 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5457 // Attributes are annotated out-of-order, skip tokens until we reach it.
5458 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005459 ? clang_getNullCursor() : parent;
5460
5461 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5462
5463 // Avoid having the cursor of an expression "overwrite" the annotation of the
5464 // variable declaration that it belongs to.
5465 // This can happen for C++ constructor expressions whose range generally
5466 // include the variable declaration, e.g.:
5467 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005468 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005469 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005470 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005471 const unsigned I = NextToken();
5472 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5473 E->getLocStart() == D->getLocation() &&
5474 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005475 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005476 AdvanceToken();
5477 }
5478 }
5479 }
5480
5481 // Before recursing into the children keep some state that we are going
5482 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5483 // extra work after the child nodes are visited.
5484 // Note that we don't call VisitChildren here to avoid traversing statements
5485 // code-recursively which can blow the stack.
5486
5487 PostChildrenInfo Info;
5488 Info.Cursor = cursor;
5489 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005490 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005491 Info.BeforeChildrenTokenIdx = NextToken();
5492 PostChildrenInfos.push_back(Info);
5493
5494 return CXChildVisit_Recurse;
5495}
5496
5497bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5498 if (PostChildrenInfos.empty())
5499 return false;
5500 const PostChildrenInfo &Info = PostChildrenInfos.back();
5501 if (!clang_equalCursors(Info.Cursor, cursor))
5502 return false;
5503
5504 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5505 const unsigned AfterChildren = NextToken();
5506 SourceRange cursorRange = Info.CursorRange;
5507
5508 // Scan the tokens that are at the end of the cursor, but are not captured
5509 // but the child cursors.
5510 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5511
5512 // Scan the tokens that are at the beginning of the cursor, but are not
5513 // capture by the child cursors.
5514 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5515 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5516 break;
5517
5518 Cursors[I] = cursor;
5519 }
5520
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005521 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5522 // encountered the attribute cursor.
5523 if (clang_isAttribute(cursor.kind))
5524 TokIdx = Info.BeforeReachingCursorIdx;
5525
Guy Benyei11169dd2012-12-18 14:30:41 +00005526 PostChildrenInfos.pop_back();
5527 return false;
5528}
5529
5530static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5531 CXCursor parent,
5532 CXClientData client_data) {
5533 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5534}
5535
5536static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5537 CXClientData client_data) {
5538 return static_cast<AnnotateTokensWorker*>(client_data)->
5539 postVisitChildren(cursor);
5540}
5541
5542namespace {
5543
5544/// \brief Uses the macro expansions in the preprocessing record to find
5545/// and mark tokens that are macro arguments. This info is used by the
5546/// AnnotateTokensWorker.
5547class MarkMacroArgTokensVisitor {
5548 SourceManager &SM;
5549 CXToken *Tokens;
5550 unsigned NumTokens;
5551 unsigned CurIdx;
5552
5553public:
5554 MarkMacroArgTokensVisitor(SourceManager &SM,
5555 CXToken *tokens, unsigned numTokens)
5556 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5557
5558 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5559 if (cursor.kind != CXCursor_MacroExpansion)
5560 return CXChildVisit_Continue;
5561
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005562 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005563 if (macroRange.getBegin() == macroRange.getEnd())
5564 return CXChildVisit_Continue; // it's not a function macro.
5565
5566 for (; CurIdx < NumTokens; ++CurIdx) {
5567 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5568 macroRange.getBegin()))
5569 break;
5570 }
5571
5572 if (CurIdx == NumTokens)
5573 return CXChildVisit_Break;
5574
5575 for (; CurIdx < NumTokens; ++CurIdx) {
5576 SourceLocation tokLoc = getTokenLoc(CurIdx);
5577 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5578 break;
5579
5580 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5581 }
5582
5583 if (CurIdx == NumTokens)
5584 return CXChildVisit_Break;
5585
5586 return CXChildVisit_Continue;
5587 }
5588
5589private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005590 CXToken &getTok(unsigned Idx) {
5591 assert(Idx < NumTokens);
5592 return Tokens[Idx];
5593 }
5594 const CXToken &getTok(unsigned Idx) const {
5595 assert(Idx < NumTokens);
5596 return Tokens[Idx];
5597 }
5598
Guy Benyei11169dd2012-12-18 14:30:41 +00005599 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005600 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005601 }
5602
5603 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5604 // The third field is reserved and currently not used. Use it here
5605 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005606 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005607 }
5608};
5609
5610} // end anonymous namespace
5611
5612static CXChildVisitResult
5613MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5614 CXClientData client_data) {
5615 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5616 parent);
5617}
5618
5619namespace {
5620 struct clang_annotateTokens_Data {
5621 CXTranslationUnit TU;
5622 ASTUnit *CXXUnit;
5623 CXToken *Tokens;
5624 unsigned NumTokens;
5625 CXCursor *Cursors;
5626 };
5627}
5628
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005629/// \brief Used by \c annotatePreprocessorTokens.
5630/// \returns true if lexing was finished, false otherwise.
5631static bool lexNext(Lexer &Lex, Token &Tok,
5632 unsigned &NextIdx, unsigned NumTokens) {
5633 if (NextIdx >= NumTokens)
5634 return true;
5635
5636 ++NextIdx;
5637 Lex.LexFromRawLexer(Tok);
5638 if (Tok.is(tok::eof))
5639 return true;
5640
5641 return false;
5642}
5643
Guy Benyei11169dd2012-12-18 14:30:41 +00005644static void annotatePreprocessorTokens(CXTranslationUnit TU,
5645 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005646 CXCursor *Cursors,
5647 CXToken *Tokens,
5648 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005649 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005650
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005651 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005652 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5653 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005654 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005655 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005656 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005657
5658 if (BeginLocInfo.first != EndLocInfo.first)
5659 return;
5660
5661 StringRef Buffer;
5662 bool Invalid = false;
5663 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5664 if (Buffer.empty() || Invalid)
5665 return;
5666
5667 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5668 CXXUnit->getASTContext().getLangOpts(),
5669 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5670 Buffer.end());
5671 Lex.SetCommentRetentionState(true);
5672
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005673 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005674 // Lex tokens in raw mode until we hit the end of the range, to avoid
5675 // entering #includes or expanding macros.
5676 while (true) {
5677 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005678 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5679 break;
5680 unsigned TokIdx = NextIdx-1;
5681 assert(Tok.getLocation() ==
5682 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005683
5684 reprocess:
5685 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005686 // We have found a preprocessing directive. Annotate the tokens
5687 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005688 //
5689 // FIXME: Some simple tests here could identify macro definitions and
5690 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005691
5692 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005693 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5694 break;
5695
5696 MacroInfo *MI = 0;
Alp Toker2d57cea2014-05-17 04:53:25 +00005697 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005698 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5699 break;
5700
5701 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005702 IdentifierInfo &II =
5703 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005704 SourceLocation MappedTokLoc =
5705 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5706 MI = getMacroInfo(II, MappedTokLoc, TU);
5707 }
5708 }
5709
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005710 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005711 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005712 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5713 finished = true;
5714 break;
5715 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005716 // If we are in a macro definition, check if the token was ever a
5717 // macro name and annotate it if that's the case.
5718 if (MI) {
5719 SourceLocation SaveLoc = Tok.getLocation();
5720 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5721 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5722 Tok.setLocation(SaveLoc);
5723 if (MacroDef)
5724 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5725 Tok.getLocation(), TU);
5726 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005727 } while (!Tok.isAtStartOfLine());
5728
5729 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5730 assert(TokIdx <= LastIdx);
5731 SourceLocation EndLoc =
5732 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5733 CXCursor Cursor =
5734 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5735
5736 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005737 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005738
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005739 if (finished)
5740 break;
5741 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005742 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005743 }
5744}
5745
5746// This gets run a separate thread to avoid stack blowout.
5747static void clang_annotateTokensImpl(void *UserData) {
5748 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5749 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5750 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5751 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5752 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5753
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005754 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005755 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5756 setThreadBackgroundPriority();
5757
5758 // Determine the region of interest, which contains all of the tokens.
5759 SourceRange RegionOfInterest;
5760 RegionOfInterest.setBegin(
5761 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5762 RegionOfInterest.setEnd(
5763 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5764 Tokens[NumTokens-1])));
5765
Guy Benyei11169dd2012-12-18 14:30:41 +00005766 // Relex the tokens within the source range to look for preprocessing
5767 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005768 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005769
5770 // If begin location points inside a macro argument, set it to the expansion
5771 // location so we can have the full context when annotating semantically.
5772 {
5773 SourceManager &SM = CXXUnit->getSourceManager();
5774 SourceLocation Loc =
5775 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5776 if (Loc.isMacroID())
5777 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5778 }
5779
Guy Benyei11169dd2012-12-18 14:30:41 +00005780 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5781 // Search and mark tokens that are macro argument expansions.
5782 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5783 Tokens, NumTokens);
5784 CursorVisitor MacroArgMarker(TU,
5785 MarkMacroArgTokensVisitorDelegate, &Visitor,
5786 /*VisitPreprocessorLast=*/true,
5787 /*VisitIncludedEntities=*/false,
5788 RegionOfInterest);
5789 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5790 }
5791
5792 // Annotate all of the source locations in the region of interest that map to
5793 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005794 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005795
5796 // FIXME: We use a ridiculous stack size here because the data-recursion
5797 // algorithm uses a large stack frame than the non-data recursive version,
5798 // and AnnotationTokensWorker currently transforms the data-recursion
5799 // algorithm back into a traditional recursion by explicitly calling
5800 // VisitChildren(). We will need to remove this explicit recursive call.
5801 W.AnnotateTokens();
5802
5803 // If we ran into any entities that involve context-sensitive keywords,
5804 // take another pass through the tokens to mark them as such.
5805 if (W.hasContextSensitiveKeywords()) {
5806 for (unsigned I = 0; I != NumTokens; ++I) {
5807 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5808 continue;
5809
5810 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5811 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005812 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005813 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5814 if (Property->getPropertyAttributesAsWritten() != 0 &&
5815 llvm::StringSwitch<bool>(II->getName())
5816 .Case("readonly", true)
5817 .Case("assign", true)
5818 .Case("unsafe_unretained", true)
5819 .Case("readwrite", true)
5820 .Case("retain", true)
5821 .Case("copy", true)
5822 .Case("nonatomic", true)
5823 .Case("atomic", true)
5824 .Case("getter", true)
5825 .Case("setter", true)
5826 .Case("strong", true)
5827 .Case("weak", true)
5828 .Default(false))
5829 Tokens[I].int_data[0] = CXToken_Keyword;
5830 }
5831 continue;
5832 }
5833
5834 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5835 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5836 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5837 if (llvm::StringSwitch<bool>(II->getName())
5838 .Case("in", true)
5839 .Case("out", true)
5840 .Case("inout", true)
5841 .Case("oneway", true)
5842 .Case("bycopy", true)
5843 .Case("byref", true)
5844 .Default(false))
5845 Tokens[I].int_data[0] = CXToken_Keyword;
5846 continue;
5847 }
5848
5849 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5850 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5851 Tokens[I].int_data[0] = CXToken_Keyword;
5852 continue;
5853 }
5854 }
5855 }
5856}
5857
5858extern "C" {
5859
5860void clang_annotateTokens(CXTranslationUnit TU,
5861 CXToken *Tokens, unsigned NumTokens,
5862 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005863 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005864 LOG_BAD_TU(TU);
5865 return;
5866 }
5867 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005868 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005869 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005870 }
5871
5872 LOG_FUNC_SECTION {
5873 *Log << TU << ' ';
5874 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5875 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5876 *Log << clang_getRange(bloc, eloc);
5877 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005878
5879 // Any token we don't specifically annotate will have a NULL cursor.
5880 CXCursor C = clang_getNullCursor();
5881 for (unsigned I = 0; I != NumTokens; ++I)
5882 Cursors[I] = C;
5883
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005884 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005885 if (!CXXUnit)
5886 return;
5887
5888 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5889
5890 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5891 llvm::CrashRecoveryContext CRC;
5892 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5893 GetSafetyThreadStackSize() * 2)) {
5894 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5895 }
5896}
5897
5898} // end: extern "C"
5899
5900//===----------------------------------------------------------------------===//
5901// Operations for querying linkage of a cursor.
5902//===----------------------------------------------------------------------===//
5903
5904extern "C" {
5905CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5906 if (!clang_isDeclaration(cursor.kind))
5907 return CXLinkage_Invalid;
5908
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005909 const Decl *D = cxcursor::getCursorDecl(cursor);
5910 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005911 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005912 case NoLinkage:
5913 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005914 case InternalLinkage: return CXLinkage_Internal;
5915 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5916 case ExternalLinkage: return CXLinkage_External;
5917 };
5918
5919 return CXLinkage_Invalid;
5920}
5921} // end: extern "C"
5922
5923//===----------------------------------------------------------------------===//
5924// Operations for querying language of a cursor.
5925//===----------------------------------------------------------------------===//
5926
5927static CXLanguageKind getDeclLanguage(const Decl *D) {
5928 if (!D)
5929 return CXLanguage_C;
5930
5931 switch (D->getKind()) {
5932 default:
5933 break;
5934 case Decl::ImplicitParam:
5935 case Decl::ObjCAtDefsField:
5936 case Decl::ObjCCategory:
5937 case Decl::ObjCCategoryImpl:
5938 case Decl::ObjCCompatibleAlias:
5939 case Decl::ObjCImplementation:
5940 case Decl::ObjCInterface:
5941 case Decl::ObjCIvar:
5942 case Decl::ObjCMethod:
5943 case Decl::ObjCProperty:
5944 case Decl::ObjCPropertyImpl:
5945 case Decl::ObjCProtocol:
5946 return CXLanguage_ObjC;
5947 case Decl::CXXConstructor:
5948 case Decl::CXXConversion:
5949 case Decl::CXXDestructor:
5950 case Decl::CXXMethod:
5951 case Decl::CXXRecord:
5952 case Decl::ClassTemplate:
5953 case Decl::ClassTemplatePartialSpecialization:
5954 case Decl::ClassTemplateSpecialization:
5955 case Decl::Friend:
5956 case Decl::FriendTemplate:
5957 case Decl::FunctionTemplate:
5958 case Decl::LinkageSpec:
5959 case Decl::Namespace:
5960 case Decl::NamespaceAlias:
5961 case Decl::NonTypeTemplateParm:
5962 case Decl::StaticAssert:
5963 case Decl::TemplateTemplateParm:
5964 case Decl::TemplateTypeParm:
5965 case Decl::UnresolvedUsingTypename:
5966 case Decl::UnresolvedUsingValue:
5967 case Decl::Using:
5968 case Decl::UsingDirective:
5969 case Decl::UsingShadow:
5970 return CXLanguage_CPlusPlus;
5971 }
5972
5973 return CXLanguage_C;
5974}
5975
5976extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005977
5978static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5979 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5980 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005981
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005982 switch (D->getAvailability()) {
5983 case AR_Available:
5984 case AR_NotYetIntroduced:
5985 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005986 return getCursorAvailabilityForDecl(
5987 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005988 return CXAvailability_Available;
5989
5990 case AR_Deprecated:
5991 return CXAvailability_Deprecated;
5992
5993 case AR_Unavailable:
5994 return CXAvailability_NotAvailable;
5995 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005996
5997 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005998}
5999
Guy Benyei11169dd2012-12-18 14:30:41 +00006000enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6001 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006002 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6003 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006004
6005 return CXAvailability_Available;
6006}
6007
6008static CXVersion convertVersion(VersionTuple In) {
6009 CXVersion Out = { -1, -1, -1 };
6010 if (In.empty())
6011 return Out;
6012
6013 Out.Major = In.getMajor();
6014
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006015 Optional<unsigned> Minor = In.getMinor();
6016 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006017 Out.Minor = *Minor;
6018 else
6019 return Out;
6020
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006021 Optional<unsigned> Subminor = In.getSubminor();
6022 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006023 Out.Subminor = *Subminor;
6024
6025 return Out;
6026}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006027
6028static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6029 int *always_deprecated,
6030 CXString *deprecated_message,
6031 int *always_unavailable,
6032 CXString *unavailable_message,
6033 CXPlatformAvailability *availability,
6034 int availability_size) {
6035 bool HadAvailAttr = false;
6036 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006037 for (auto A : D->attrs()) {
6038 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006039 HadAvailAttr = true;
6040 if (always_deprecated)
6041 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006042 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006043 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006044 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006045 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006046 continue;
6047 }
6048
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006049 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006050 HadAvailAttr = true;
6051 if (always_unavailable)
6052 *always_unavailable = 1;
6053 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006054 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006055 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6056 }
6057 continue;
6058 }
6059
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006060 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006061 HadAvailAttr = true;
6062 if (N < availability_size) {
6063 availability[N].Platform
6064 = cxstring::createDup(Avail->getPlatform()->getName());
6065 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6066 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6067 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6068 availability[N].Unavailable = Avail->getUnavailable();
6069 availability[N].Message = cxstring::createDup(Avail->getMessage());
6070 }
6071 ++N;
6072 }
6073 }
6074
6075 if (!HadAvailAttr)
6076 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6077 return getCursorPlatformAvailabilityForDecl(
6078 cast<Decl>(EnumConst->getDeclContext()),
6079 always_deprecated,
6080 deprecated_message,
6081 always_unavailable,
6082 unavailable_message,
6083 availability,
6084 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006085
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006086 return N;
6087}
6088
Guy Benyei11169dd2012-12-18 14:30:41 +00006089int clang_getCursorPlatformAvailability(CXCursor cursor,
6090 int *always_deprecated,
6091 CXString *deprecated_message,
6092 int *always_unavailable,
6093 CXString *unavailable_message,
6094 CXPlatformAvailability *availability,
6095 int availability_size) {
6096 if (always_deprecated)
6097 *always_deprecated = 0;
6098 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006099 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006100 if (always_unavailable)
6101 *always_unavailable = 0;
6102 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006103 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006104
Guy Benyei11169dd2012-12-18 14:30:41 +00006105 if (!clang_isDeclaration(cursor.kind))
6106 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006107
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006108 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006109 if (!D)
6110 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006111
6112 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6113 deprecated_message,
6114 always_unavailable,
6115 unavailable_message,
6116 availability,
6117 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006118}
6119
6120void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6121 clang_disposeString(availability->Platform);
6122 clang_disposeString(availability->Message);
6123}
6124
6125CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6126 if (clang_isDeclaration(cursor.kind))
6127 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6128
6129 return CXLanguage_Invalid;
6130}
6131
6132 /// \brief If the given cursor is the "templated" declaration
6133 /// descibing a class or function template, return the class or
6134 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006135static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006136 if (!D)
6137 return 0;
6138
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006139 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006140 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6141 return FunTmpl;
6142
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006143 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006144 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6145 return ClassTmpl;
6146
6147 return D;
6148}
6149
6150CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6151 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006152 if (const Decl *D = getCursorDecl(cursor)) {
6153 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006154 if (!DC)
6155 return clang_getNullCursor();
6156
6157 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6158 getCursorTU(cursor));
6159 }
6160 }
6161
6162 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006163 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006164 return MakeCXCursor(D, getCursorTU(cursor));
6165 }
6166
6167 return clang_getNullCursor();
6168}
6169
6170CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6171 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006172 if (const Decl *D = getCursorDecl(cursor)) {
6173 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006174 if (!DC)
6175 return clang_getNullCursor();
6176
6177 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6178 getCursorTU(cursor));
6179 }
6180 }
6181
6182 // FIXME: Note that we can't easily compute the lexical context of a
6183 // statement or expression, so we return nothing.
6184 return clang_getNullCursor();
6185}
6186
6187CXFile clang_getIncludedFile(CXCursor cursor) {
6188 if (cursor.kind != CXCursor_InclusionDirective)
6189 return 0;
6190
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006191 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006192 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006193}
6194
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006195unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6196 if (C.kind != CXCursor_ObjCPropertyDecl)
6197 return CXObjCPropertyAttr_noattr;
6198
6199 unsigned Result = CXObjCPropertyAttr_noattr;
6200 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6201 ObjCPropertyDecl::PropertyAttributeKind Attr =
6202 PD->getPropertyAttributesAsWritten();
6203
6204#define SET_CXOBJCPROP_ATTR(A) \
6205 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6206 Result |= CXObjCPropertyAttr_##A
6207 SET_CXOBJCPROP_ATTR(readonly);
6208 SET_CXOBJCPROP_ATTR(getter);
6209 SET_CXOBJCPROP_ATTR(assign);
6210 SET_CXOBJCPROP_ATTR(readwrite);
6211 SET_CXOBJCPROP_ATTR(retain);
6212 SET_CXOBJCPROP_ATTR(copy);
6213 SET_CXOBJCPROP_ATTR(nonatomic);
6214 SET_CXOBJCPROP_ATTR(setter);
6215 SET_CXOBJCPROP_ATTR(atomic);
6216 SET_CXOBJCPROP_ATTR(weak);
6217 SET_CXOBJCPROP_ATTR(strong);
6218 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6219#undef SET_CXOBJCPROP_ATTR
6220
6221 return Result;
6222}
6223
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006224unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6225 if (!clang_isDeclaration(C.kind))
6226 return CXObjCDeclQualifier_None;
6227
6228 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6229 const Decl *D = getCursorDecl(C);
6230 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6231 QT = MD->getObjCDeclQualifier();
6232 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6233 QT = PD->getObjCDeclQualifier();
6234 if (QT == Decl::OBJC_TQ_None)
6235 return CXObjCDeclQualifier_None;
6236
6237 unsigned Result = CXObjCDeclQualifier_None;
6238 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6239 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6240 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6241 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6242 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6243 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6244
6245 return Result;
6246}
6247
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006248unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6249 if (!clang_isDeclaration(C.kind))
6250 return 0;
6251
6252 const Decl *D = getCursorDecl(C);
6253 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6254 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6255 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6256 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6257
6258 return 0;
6259}
6260
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006261unsigned clang_Cursor_isVariadic(CXCursor C) {
6262 if (!clang_isDeclaration(C.kind))
6263 return 0;
6264
6265 const Decl *D = getCursorDecl(C);
6266 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6267 return FD->isVariadic();
6268 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6269 return MD->isVariadic();
6270
6271 return 0;
6272}
6273
Guy Benyei11169dd2012-12-18 14:30:41 +00006274CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6275 if (!clang_isDeclaration(C.kind))
6276 return clang_getNullRange();
6277
6278 const Decl *D = getCursorDecl(C);
6279 ASTContext &Context = getCursorContext(C);
6280 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6281 if (!RC)
6282 return clang_getNullRange();
6283
6284 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6285}
6286
6287CXString clang_Cursor_getRawCommentText(CXCursor C) {
6288 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006289 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006290
6291 const Decl *D = getCursorDecl(C);
6292 ASTContext &Context = getCursorContext(C);
6293 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6294 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6295 StringRef();
6296
6297 // Don't duplicate the string because RawText points directly into source
6298 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006299 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006300}
6301
6302CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6303 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006304 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006305
6306 const Decl *D = getCursorDecl(C);
6307 const ASTContext &Context = getCursorContext(C);
6308 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6309
6310 if (RC) {
6311 StringRef BriefText = RC->getBriefText(Context);
6312
6313 // Don't duplicate the string because RawComment ensures that this memory
6314 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006315 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006316 }
6317
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006318 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006319}
6320
Guy Benyei11169dd2012-12-18 14:30:41 +00006321CXModule clang_Cursor_getModule(CXCursor C) {
6322 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006323 if (const ImportDecl *ImportD =
6324 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006325 return ImportD->getImportedModule();
6326 }
6327
6328 return 0;
6329}
6330
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006331CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6332 if (isNotUsableTU(TU)) {
6333 LOG_BAD_TU(TU);
6334 return nullptr;
6335 }
6336 if (!File)
6337 return nullptr;
6338 FileEntry *FE = static_cast<FileEntry *>(File);
6339
6340 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6341 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6342 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6343
6344 if (Module *Mod = Header.getModule()) {
6345 if (Header.getRole() != ModuleMap::ExcludedHeader)
6346 return Mod;
6347 }
6348 return nullptr;
6349}
6350
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006351CXFile clang_Module_getASTFile(CXModule CXMod) {
6352 if (!CXMod)
6353 return 0;
6354 Module *Mod = static_cast<Module*>(CXMod);
6355 return const_cast<FileEntry *>(Mod->getASTFile());
6356}
6357
Guy Benyei11169dd2012-12-18 14:30:41 +00006358CXModule clang_Module_getParent(CXModule CXMod) {
6359 if (!CXMod)
6360 return 0;
6361 Module *Mod = static_cast<Module*>(CXMod);
6362 return Mod->Parent;
6363}
6364
6365CXString clang_Module_getName(CXModule CXMod) {
6366 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006367 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006368 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006369 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006370}
6371
6372CXString clang_Module_getFullName(CXModule CXMod) {
6373 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006374 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006375 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006376 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006377}
6378
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006379int clang_Module_isSystem(CXModule CXMod) {
6380 if (!CXMod)
6381 return 0;
6382 Module *Mod = static_cast<Module*>(CXMod);
6383 return Mod->IsSystem;
6384}
6385
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006386unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6387 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006388 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006389 LOG_BAD_TU(TU);
6390 return 0;
6391 }
6392 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006393 return 0;
6394 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006395 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6396 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6397 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006398}
6399
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006400CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6401 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006402 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006403 LOG_BAD_TU(TU);
6404 return 0;
6405 }
6406 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006407 return 0;
6408 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006409 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006410
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006411 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6412 if (Index < TopHeaders.size())
6413 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006414
6415 return 0;
6416}
6417
6418} // end: extern "C"
6419
6420//===----------------------------------------------------------------------===//
6421// C++ AST instrospection.
6422//===----------------------------------------------------------------------===//
6423
6424extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006425unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6426 if (!clang_isDeclaration(C.kind))
6427 return 0;
6428
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006429 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006430 const CXXMethodDecl *Method =
6431 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006432 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6433}
6434
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006435unsigned clang_CXXMethod_isConst(CXCursor C) {
6436 if (!clang_isDeclaration(C.kind))
6437 return 0;
6438
6439 const Decl *D = cxcursor::getCursorDecl(C);
6440 const CXXMethodDecl *Method =
6441 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
6442 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6443}
6444
Guy Benyei11169dd2012-12-18 14:30:41 +00006445unsigned clang_CXXMethod_isStatic(CXCursor C) {
6446 if (!clang_isDeclaration(C.kind))
6447 return 0;
6448
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006449 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006450 const CXXMethodDecl *Method =
6451 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006452 return (Method && Method->isStatic()) ? 1 : 0;
6453}
6454
6455unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6456 if (!clang_isDeclaration(C.kind))
6457 return 0;
6458
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006459 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006460 const CXXMethodDecl *Method =
6461 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006462 return (Method && Method->isVirtual()) ? 1 : 0;
6463}
6464} // end: extern "C"
6465
6466//===----------------------------------------------------------------------===//
6467// Attribute introspection.
6468//===----------------------------------------------------------------------===//
6469
6470extern "C" {
6471CXType clang_getIBOutletCollectionType(CXCursor C) {
6472 if (C.kind != CXCursor_IBOutletCollectionAttr)
6473 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6474
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006475 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006476 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6477
6478 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6479}
6480} // end: extern "C"
6481
6482//===----------------------------------------------------------------------===//
6483// Inspecting memory usage.
6484//===----------------------------------------------------------------------===//
6485
6486typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6487
6488static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6489 enum CXTUResourceUsageKind k,
6490 unsigned long amount) {
6491 CXTUResourceUsageEntry entry = { k, amount };
6492 entries.push_back(entry);
6493}
6494
6495extern "C" {
6496
6497const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6498 const char *str = "";
6499 switch (kind) {
6500 case CXTUResourceUsage_AST:
6501 str = "ASTContext: expressions, declarations, and types";
6502 break;
6503 case CXTUResourceUsage_Identifiers:
6504 str = "ASTContext: identifiers";
6505 break;
6506 case CXTUResourceUsage_Selectors:
6507 str = "ASTContext: selectors";
6508 break;
6509 case CXTUResourceUsage_GlobalCompletionResults:
6510 str = "Code completion: cached global results";
6511 break;
6512 case CXTUResourceUsage_SourceManagerContentCache:
6513 str = "SourceManager: content cache allocator";
6514 break;
6515 case CXTUResourceUsage_AST_SideTables:
6516 str = "ASTContext: side tables";
6517 break;
6518 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6519 str = "SourceManager: malloc'ed memory buffers";
6520 break;
6521 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6522 str = "SourceManager: mmap'ed memory buffers";
6523 break;
6524 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6525 str = "ExternalASTSource: malloc'ed memory buffers";
6526 break;
6527 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6528 str = "ExternalASTSource: mmap'ed memory buffers";
6529 break;
6530 case CXTUResourceUsage_Preprocessor:
6531 str = "Preprocessor: malloc'ed memory";
6532 break;
6533 case CXTUResourceUsage_PreprocessingRecord:
6534 str = "Preprocessor: PreprocessingRecord";
6535 break;
6536 case CXTUResourceUsage_SourceManager_DataStructures:
6537 str = "SourceManager: data structures and tables";
6538 break;
6539 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6540 str = "Preprocessor: header search tables";
6541 break;
6542 }
6543 return str;
6544}
6545
6546CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006547 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006548 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006549 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6550 return usage;
6551 }
6552
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006553 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006554 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006555 ASTContext &astContext = astUnit->getASTContext();
6556
6557 // How much memory is used by AST nodes and types?
6558 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6559 (unsigned long) astContext.getASTAllocatedMemory());
6560
6561 // How much memory is used by identifiers?
6562 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6563 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6564
6565 // How much memory is used for selectors?
6566 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6567 (unsigned long) astContext.Selectors.getTotalMemory());
6568
6569 // How much memory is used by ASTContext's side tables?
6570 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6571 (unsigned long) astContext.getSideTableAllocatedMemory());
6572
6573 // How much memory is used for caching global code completion results?
6574 unsigned long completionBytes = 0;
6575 if (GlobalCodeCompletionAllocator *completionAllocator =
6576 astUnit->getCachedCompletionAllocator().getPtr()) {
6577 completionBytes = completionAllocator->getTotalMemory();
6578 }
6579 createCXTUResourceUsageEntry(*entries,
6580 CXTUResourceUsage_GlobalCompletionResults,
6581 completionBytes);
6582
6583 // How much memory is being used by SourceManager's content cache?
6584 createCXTUResourceUsageEntry(*entries,
6585 CXTUResourceUsage_SourceManagerContentCache,
6586 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6587
6588 // How much memory is being used by the MemoryBuffer's in SourceManager?
6589 const SourceManager::MemoryBufferSizes &srcBufs =
6590 astUnit->getSourceManager().getMemoryBufferSizes();
6591
6592 createCXTUResourceUsageEntry(*entries,
6593 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6594 (unsigned long) srcBufs.malloc_bytes);
6595 createCXTUResourceUsageEntry(*entries,
6596 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6597 (unsigned long) srcBufs.mmap_bytes);
6598 createCXTUResourceUsageEntry(*entries,
6599 CXTUResourceUsage_SourceManager_DataStructures,
6600 (unsigned long) astContext.getSourceManager()
6601 .getDataStructureSizes());
6602
6603 // How much memory is being used by the ExternalASTSource?
6604 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6605 const ExternalASTSource::MemoryBufferSizes &sizes =
6606 esrc->getMemoryBufferSizes();
6607
6608 createCXTUResourceUsageEntry(*entries,
6609 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6610 (unsigned long) sizes.malloc_bytes);
6611 createCXTUResourceUsageEntry(*entries,
6612 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6613 (unsigned long) sizes.mmap_bytes);
6614 }
6615
6616 // How much memory is being used by the Preprocessor?
6617 Preprocessor &pp = astUnit->getPreprocessor();
6618 createCXTUResourceUsageEntry(*entries,
6619 CXTUResourceUsage_Preprocessor,
6620 pp.getTotalMemory());
6621
6622 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6623 createCXTUResourceUsageEntry(*entries,
6624 CXTUResourceUsage_PreprocessingRecord,
6625 pRec->getTotalMemory());
6626 }
6627
6628 createCXTUResourceUsageEntry(*entries,
6629 CXTUResourceUsage_Preprocessor_HeaderSearch,
6630 pp.getHeaderSearchInfo().getTotalMemory());
6631
6632 CXTUResourceUsage usage = { (void*) entries.get(),
6633 (unsigned) entries->size(),
6634 entries->size() ? &(*entries)[0] : 0 };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006635 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006636 return usage;
6637}
6638
6639void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6640 if (usage.data)
6641 delete (MemUsageEntries*) usage.data;
6642}
6643
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006644CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6645 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006646 skipped->count = 0;
6647 skipped->ranges = 0;
6648
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006649 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006650 LOG_BAD_TU(TU);
6651 return skipped;
6652 }
6653
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006654 if (!file)
6655 return skipped;
6656
6657 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6658 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6659 if (!ppRec)
6660 return skipped;
6661
6662 ASTContext &Ctx = astUnit->getASTContext();
6663 SourceManager &sm = Ctx.getSourceManager();
6664 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6665 FileID wantedFileID = sm.translateFile(fileEntry);
6666
6667 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6668 std::vector<SourceRange> wantedRanges;
6669 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6670 i != ei; ++i) {
6671 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6672 wantedRanges.push_back(*i);
6673 }
6674
6675 skipped->count = wantedRanges.size();
6676 skipped->ranges = new CXSourceRange[skipped->count];
6677 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6678 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6679
6680 return skipped;
6681}
6682
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006683void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6684 if (ranges) {
6685 delete[] ranges->ranges;
6686 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006687 }
6688}
6689
Guy Benyei11169dd2012-12-18 14:30:41 +00006690} // end extern "C"
6691
6692void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6693 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6694 for (unsigned I = 0; I != Usage.numEntries; ++I)
6695 fprintf(stderr, " %s: %lu\n",
6696 clang_getTUResourceUsageName(Usage.entries[I].kind),
6697 Usage.entries[I].amount);
6698
6699 clang_disposeCXTUResourceUsage(Usage);
6700}
6701
6702//===----------------------------------------------------------------------===//
6703// Misc. utility functions.
6704//===----------------------------------------------------------------------===//
6705
6706/// Default to using an 8 MB stack size on "safety" threads.
6707static unsigned SafetyStackThreadSize = 8 << 20;
6708
6709namespace clang {
6710
6711bool RunSafely(llvm::CrashRecoveryContext &CRC,
6712 void (*Fn)(void*), void *UserData,
6713 unsigned Size) {
6714 if (!Size)
6715 Size = GetSafetyThreadStackSize();
6716 if (Size)
6717 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6718 return CRC.RunSafely(Fn, UserData);
6719}
6720
6721unsigned GetSafetyThreadStackSize() {
6722 return SafetyStackThreadSize;
6723}
6724
6725void SetSafetyThreadStackSize(unsigned Value) {
6726 SafetyStackThreadSize = Value;
6727}
6728
6729}
6730
6731void clang::setThreadBackgroundPriority() {
6732 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6733 return;
6734
6735 // FIXME: Move to llvm/Support and make it cross-platform.
6736#ifdef __APPLE__
6737 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6738#endif
6739}
6740
6741void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6742 if (!Unit)
6743 return;
6744
6745 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6746 DEnd = Unit->stored_diag_end();
6747 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006748 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006749 CXString Msg = clang_formatDiagnostic(&Diag,
6750 clang_defaultDiagnosticDisplayOptions());
6751 fprintf(stderr, "%s\n", clang_getCString(Msg));
6752 clang_disposeString(Msg);
6753 }
6754#ifdef LLVM_ON_WIN32
6755 // On Windows, force a flush, since there may be multiple copies of
6756 // stderr and stdout in the file system, all with different buffers
6757 // but writing to the same device.
6758 fflush(stderr);
6759#endif
6760}
6761
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006762MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6763 SourceLocation MacroDefLoc,
6764 CXTranslationUnit TU){
6765 if (MacroDefLoc.isInvalid() || !TU)
6766 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006767 if (!II.hadMacroDefinition())
6768 return 0;
6769
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006770 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006771 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006772 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006773 if (MD) {
6774 for (MacroDirective::DefInfo
6775 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6776 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6777 return Def.getMacroInfo();
6778 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006779 }
6780
6781 return 0;
6782}
6783
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006784const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6785 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006786 if (!MacroDef || !TU)
6787 return 0;
6788 const IdentifierInfo *II = MacroDef->getName();
6789 if (!II)
6790 return 0;
6791
6792 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6793}
6794
6795MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6796 const Token &Tok,
6797 CXTranslationUnit TU) {
6798 if (!MI || !TU)
6799 return 0;
6800 if (Tok.isNot(tok::raw_identifier))
6801 return 0;
6802
6803 if (MI->getNumTokens() == 0)
6804 return 0;
6805 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6806 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006807 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006808
6809 // Check that the token is inside the definition and not its argument list.
6810 SourceManager &SM = Unit->getSourceManager();
6811 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6812 return 0;
6813 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6814 return 0;
6815
6816 Preprocessor &PP = Unit->getPreprocessor();
6817 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6818 if (!PPRec)
6819 return 0;
6820
Alp Toker2d57cea2014-05-17 04:53:25 +00006821 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006822 if (!II.hadMacroDefinition())
6823 return 0;
6824
6825 // Check that the identifier is not one of the macro arguments.
6826 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6827 return 0;
6828
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006829 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6830 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006831 return 0;
6832
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006833 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006834}
6835
6836MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6837 SourceLocation Loc,
6838 CXTranslationUnit TU) {
6839 if (Loc.isInvalid() || !MI || !TU)
6840 return 0;
6841
6842 if (MI->getNumTokens() == 0)
6843 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006844 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006845 Preprocessor &PP = Unit->getPreprocessor();
6846 if (!PP.getPreprocessingRecord())
6847 return 0;
6848 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6849 Token Tok;
6850 if (PP.getRawToken(Loc, Tok))
6851 return 0;
6852
6853 return checkForMacroInMacroDefinition(MI, Tok, TU);
6854}
6855
Guy Benyei11169dd2012-12-18 14:30:41 +00006856extern "C" {
6857
6858CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006859 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006860}
6861
6862} // end: extern "C"
6863
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006864Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6865 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006866 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006867 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006868 if (Unit->isMainFileAST())
6869 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006870 return *this;
6871 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006872 } else {
6873 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006874 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006875 return *this;
6876}
6877
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006878Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6879 *this << FE->getName();
6880 return *this;
6881}
6882
6883Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6884 CXString cursorName = clang_getCursorDisplayName(cursor);
6885 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6886 clang_disposeString(cursorName);
6887 return *this;
6888}
6889
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006890Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6891 CXFile File;
6892 unsigned Line, Column;
6893 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6894 CXString FileName = clang_getFileName(File);
6895 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6896 clang_disposeString(FileName);
6897 return *this;
6898}
6899
6900Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6901 CXSourceLocation BLoc = clang_getRangeStart(range);
6902 CXSourceLocation ELoc = clang_getRangeEnd(range);
6903
6904 CXFile BFile;
6905 unsigned BLine, BColumn;
6906 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6907
6908 CXFile EFile;
6909 unsigned ELine, EColumn;
6910 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6911
6912 CXString BFileName = clang_getFileName(BFile);
6913 if (BFile == EFile) {
6914 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6915 BLine, BColumn, ELine, EColumn);
6916 } else {
6917 CXString EFileName = clang_getFileName(EFile);
6918 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6919 BLine, BColumn)
6920 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6921 ELine, EColumn);
6922 clang_disposeString(EFileName);
6923 }
6924 clang_disposeString(BFileName);
6925 return *this;
6926}
6927
6928Logger &cxindex::Logger::operator<<(CXString Str) {
6929 *this << clang_getCString(Str);
6930 return *this;
6931}
6932
6933Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6934 LogOS << Fmt;
6935 return *this;
6936}
6937
6938cxindex::Logger::~Logger() {
6939 LogOS.flush();
6940
6941 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6942
6943 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6944
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006945 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006946 OS << "[libclang:" << Name << ':';
6947
6948 // FIXME: Portability.
6949#if HAVE_PTHREAD_H && __APPLE__
6950 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6951 OS << tid << ':';
6952#endif
6953
6954 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6955 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6956 OS << Msg.str() << '\n';
6957
6958 if (Trace) {
6959 llvm::sys::PrintStackTrace(stderr);
6960 OS << "--------------------------------------------------\n";
6961 }
6962}