blob: 26b3bf16af2d1ea4d088ca165b00be8f8953348f [file] [log] [blame]
Guy Benyei11169dd2012-12-18 14:30:41 +00001//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the main API hooks in the Clang-C Source Indexing
11// library.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CIndexer.h"
16#include "CIndexDiagnostic.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000017#include "CLog.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000018#include "CXCursor.h"
19#include "CXSourceLocation.h"
20#include "CXString.h"
21#include "CXTranslationUnit.h"
22#include "CXType.h"
23#include "CursorVisitor.h"
David Blaikie0a4e61f2013-09-13 18:32:52 +000024#include "clang/AST/Attr.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000025#include "clang/AST/StmtVisitor.h"
26#include "clang/Basic/Diagnostic.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000027#include "clang/Basic/DiagnosticCategories.h"
28#include "clang/Basic/DiagnosticIDs.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000029#include "clang/Basic/Version.h"
30#include "clang/Frontend/ASTUnit.h"
31#include "clang/Frontend/CompilerInstance.h"
32#include "clang/Frontend/FrontendDiagnostic.h"
Dmitri Gribenko9e605112013-11-13 22:16:51 +000033#include "clang/Index/CommentToXML.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000034#include "clang/Lex/HeaderSearch.h"
35#include "clang/Lex/Lexer.h"
36#include "clang/Lex/PreprocessingRecord.h"
37#include "clang/Lex/Preprocessor.h"
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000038#include "clang/Serialization/SerializationDiagnostic.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000039#include "llvm/ADT/Optional.h"
40#include "llvm/ADT/STLExtras.h"
41#include "llvm/ADT/StringSwitch.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000042#include "llvm/Config/config.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000043#include "llvm/Support/Compiler.h"
44#include "llvm/Support/CrashRecoveryContext.h"
Chandler Carruth4b417452013-01-19 08:09:44 +000045#include "llvm/Support/Format.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000046#include "llvm/Support/MemoryBuffer.h"
47#include "llvm/Support/Mutex.h"
Guy Benyei11169dd2012-12-18 14:30:41 +000048#include "llvm/Support/Program.h"
49#include "llvm/Support/SaveAndRestore.h"
50#include "llvm/Support/Signals.h"
51#include "llvm/Support/Threading.h"
52#include "llvm/Support/Timer.h"
53#include "llvm/Support/raw_ostream.h"
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000054
55#if HAVE_PTHREAD_H
56#include <pthread.h>
57#endif
Guy Benyei11169dd2012-12-18 14:30:41 +000058
59using namespace clang;
60using namespace clang::cxcursor;
Guy Benyei11169dd2012-12-18 14:30:41 +000061using namespace clang::cxtu;
62using namespace clang::cxindex;
63
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000064CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, ASTUnit *AU) {
65 if (!AU)
Guy Benyei11169dd2012-12-18 14:30:41 +000066 return 0;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000067 assert(CIdx);
Guy Benyei11169dd2012-12-18 14:30:41 +000068 CXTranslationUnit D = new CXTranslationUnitImpl();
69 D->CIdx = CIdx;
Dmitri Gribenkod36209e2013-01-26 21:32:42 +000070 D->TheASTUnit = AU;
Dmitri Gribenko74895212013-02-03 13:52:47 +000071 D->StringPool = new cxstring::CXStringPool();
Guy Benyei11169dd2012-12-18 14:30:41 +000072 D->Diagnostics = 0;
73 D->OverridenCursorsPool = createOverridenCXCursorsPool();
Dmitri Gribenko9e605112013-11-13 22:16:51 +000074 D->CommentToXML = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +000075 return D;
76}
77
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +000078bool cxtu::isASTReadError(ASTUnit *AU) {
79 for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
80 DEnd = AU->stored_diag_end();
81 D != DEnd; ++D) {
82 if (D->getLevel() >= DiagnosticsEngine::Error &&
83 DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
84 diag::DiagCat_AST_Deserialization_Issue)
85 return true;
86 }
87 return false;
88}
89
Guy Benyei11169dd2012-12-18 14:30:41 +000090cxtu::CXTUOwner::~CXTUOwner() {
91 if (TU)
92 clang_disposeTranslationUnit(TU);
93}
94
95/// \brief Compare two source ranges to determine their relative position in
96/// the translation unit.
97static RangeComparisonResult RangeCompare(SourceManager &SM,
98 SourceRange R1,
99 SourceRange R2) {
100 assert(R1.isValid() && "First range is invalid?");
101 assert(R2.isValid() && "Second range is invalid?");
102 if (R1.getEnd() != R2.getBegin() &&
103 SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
104 return RangeBefore;
105 if (R2.getEnd() != R1.getBegin() &&
106 SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
107 return RangeAfter;
108 return RangeOverlap;
109}
110
111/// \brief Determine if a source location falls within, before, or after a
112/// a given source range.
113static RangeComparisonResult LocationCompare(SourceManager &SM,
114 SourceLocation L, SourceRange R) {
115 assert(R.isValid() && "First range is invalid?");
116 assert(L.isValid() && "Second range is invalid?");
117 if (L == R.getBegin() || L == R.getEnd())
118 return RangeOverlap;
119 if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
120 return RangeBefore;
121 if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
122 return RangeAfter;
123 return RangeOverlap;
124}
125
126/// \brief Translate a Clang source range into a CIndex source range.
127///
128/// Clang internally represents ranges where the end location points to the
129/// start of the token at the end. However, for external clients it is more
130/// useful to have a CXSourceRange be a proper half-open interval. This routine
131/// does the appropriate translation.
132CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
133 const LangOptions &LangOpts,
134 const CharSourceRange &R) {
135 // We want the last character in this location, so we will adjust the
136 // location accordingly.
137 SourceLocation EndLoc = R.getEnd();
138 if (EndLoc.isValid() && EndLoc.isMacroID() && !SM.isMacroArgExpansion(EndLoc))
139 EndLoc = SM.getExpansionRange(EndLoc).second;
140 if (R.isTokenRange() && !EndLoc.isInvalid()) {
141 unsigned Length = Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc),
142 SM, LangOpts);
143 EndLoc = EndLoc.getLocWithOffset(Length);
144 }
145
Bill Wendlingeade3622013-01-23 08:25:41 +0000146 CXSourceRange Result = {
Dmitri Gribenkof9304482013-01-23 15:56:07 +0000147 { &SM, &LangOpts },
Bill Wendlingeade3622013-01-23 08:25:41 +0000148 R.getBegin().getRawEncoding(),
149 EndLoc.getRawEncoding()
150 };
Guy Benyei11169dd2012-12-18 14:30:41 +0000151 return Result;
152}
153
154//===----------------------------------------------------------------------===//
155// Cursor visitor.
156//===----------------------------------------------------------------------===//
157
158static SourceRange getRawCursorExtent(CXCursor C);
159static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);
160
161
162RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
163 return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
164}
165
166/// \brief Visit the given cursor and, if requested by the visitor,
167/// its children.
168///
169/// \param Cursor the cursor to visit.
170///
171/// \param CheckedRegionOfInterest if true, then the caller already checked
172/// that this cursor is within the region of interest.
173///
174/// \returns true if the visitation should be aborted, false if it
175/// should continue.
176bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
177 if (clang_isInvalid(Cursor.kind))
178 return false;
179
180 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000181 const Decl *D = getCursorDecl(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000182 if (!D) {
183 assert(0 && "Invalid declaration cursor");
184 return true; // abort.
185 }
186
187 // Ignore implicit declarations, unless it's an objc method because
188 // currently we should report implicit methods for properties when indexing.
189 if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
190 return false;
191 }
192
193 // If we have a range of interest, and this cursor doesn't intersect with it,
194 // we're done.
195 if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
196 SourceRange Range = getRawCursorExtent(Cursor);
197 if (Range.isInvalid() || CompareRegionOfInterest(Range))
198 return false;
199 }
200
201 switch (Visitor(Cursor, Parent, ClientData)) {
202 case CXChildVisit_Break:
203 return true;
204
205 case CXChildVisit_Continue:
206 return false;
207
208 case CXChildVisit_Recurse: {
209 bool ret = VisitChildren(Cursor);
210 if (PostChildrenVisitor)
211 if (PostChildrenVisitor(Cursor, ClientData))
212 return true;
213 return ret;
214 }
215 }
216
217 llvm_unreachable("Invalid CXChildVisitResult!");
218}
219
220static bool visitPreprocessedEntitiesInRange(SourceRange R,
221 PreprocessingRecord &PPRec,
222 CursorVisitor &Visitor) {
223 SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
224 FileID FID;
225
226 if (!Visitor.shouldVisitIncludedEntities()) {
227 // If the begin/end of the range lie in the same FileID, do the optimization
228 // where we skip preprocessed entities that do not come from the same FileID.
229 FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
230 if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
231 FID = FileID();
232 }
233
234 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
235 Entities = PPRec.getPreprocessedEntitiesInRange(R);
236 return Visitor.visitPreprocessedEntities(Entities.first, Entities.second,
237 PPRec, FID);
238}
239
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000240bool CursorVisitor::visitFileRegion() {
Guy Benyei11169dd2012-12-18 14:30:41 +0000241 if (RegionOfInterest.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000242 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000243
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000244 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000245 SourceManager &SM = Unit->getSourceManager();
246
247 std::pair<FileID, unsigned>
248 Begin = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getBegin())),
249 End = SM.getDecomposedLoc(SM.getFileLoc(RegionOfInterest.getEnd()));
250
251 if (End.first != Begin.first) {
252 // If the end does not reside in the same file, try to recover by
253 // picking the end of the file of begin location.
254 End.first = Begin.first;
255 End.second = SM.getFileIDSize(Begin.first);
256 }
257
258 assert(Begin.first == End.first);
259 if (Begin.second > End.second)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000260 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000261
262 FileID File = Begin.first;
263 unsigned Offset = Begin.second;
264 unsigned Length = End.second - Begin.second;
265
266 if (!VisitDeclsOnly && !VisitPreprocessorLast)
267 if (visitPreprocessedEntitiesInRegion())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000268 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000269
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000270 if (visitDeclsFromFileRegion(File, Offset, Length))
271 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000272
273 if (!VisitDeclsOnly && VisitPreprocessorLast)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000274 return visitPreprocessedEntitiesInRegion();
275
276 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000277}
278
279static bool isInLexicalContext(Decl *D, DeclContext *DC) {
280 if (!DC)
281 return false;
282
283 for (DeclContext *DeclDC = D->getLexicalDeclContext();
284 DeclDC; DeclDC = DeclDC->getLexicalParent()) {
285 if (DeclDC == DC)
286 return true;
287 }
288 return false;
289}
290
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000291bool CursorVisitor::visitDeclsFromFileRegion(FileID File,
Guy Benyei11169dd2012-12-18 14:30:41 +0000292 unsigned Offset, unsigned Length) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000293 ASTUnit *Unit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000294 SourceManager &SM = Unit->getSourceManager();
295 SourceRange Range = RegionOfInterest;
296
297 SmallVector<Decl *, 16> Decls;
298 Unit->findFileRegionDecls(File, Offset, Length, Decls);
299
300 // If we didn't find any file level decls for the file, try looking at the
301 // file that it was included from.
302 while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
303 bool Invalid = false;
304 const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
305 if (Invalid)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000306 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000307
308 SourceLocation Outer;
309 if (SLEntry.isFile())
310 Outer = SLEntry.getFile().getIncludeLoc();
311 else
312 Outer = SLEntry.getExpansion().getExpansionLocStart();
313 if (Outer.isInvalid())
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000314 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000315
Benjamin Kramer867ea1d2014-03-02 13:01:17 +0000316 std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
Guy Benyei11169dd2012-12-18 14:30:41 +0000317 Length = 0;
318 Unit->findFileRegionDecls(File, Offset, Length, Decls);
319 }
320
321 assert(!Decls.empty());
322
323 bool VisitedAtLeastOnce = false;
324 DeclContext *CurDC = 0;
Craig Topper2341c0d2013-07-04 03:08:24 +0000325 SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
326 for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000327 Decl *D = *DIt;
328 if (D->getSourceRange().isInvalid())
329 continue;
330
331 if (isInLexicalContext(D, CurDC))
332 continue;
333
334 CurDC = dyn_cast<DeclContext>(D);
335
336 if (TagDecl *TD = dyn_cast<TagDecl>(D))
337 if (!TD->isFreeStanding())
338 continue;
339
340 RangeComparisonResult CompRes = RangeCompare(SM, D->getSourceRange(),Range);
341 if (CompRes == RangeBefore)
342 continue;
343 if (CompRes == RangeAfter)
344 break;
345
346 assert(CompRes == RangeOverlap);
347 VisitedAtLeastOnce = true;
348
349 if (isa<ObjCContainerDecl>(D)) {
350 FileDI_current = &DIt;
351 FileDE_current = DE;
352 } else {
353 FileDI_current = 0;
354 }
355
356 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000357 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000358 }
359
360 if (VisitedAtLeastOnce)
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000361 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000362
363 // No Decls overlapped with the range. Move up the lexical context until there
364 // is a context that contains the range or we reach the translation unit
365 // level.
366 DeclContext *DC = DIt == Decls.begin() ? (*DIt)->getLexicalDeclContext()
367 : (*(DIt-1))->getLexicalDeclContext();
368
369 while (DC && !DC->isTranslationUnit()) {
370 Decl *D = cast<Decl>(DC);
371 SourceRange CurDeclRange = D->getSourceRange();
372 if (CurDeclRange.isInvalid())
373 break;
374
375 if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000376 if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
377 return true; // visitation break.
Guy Benyei11169dd2012-12-18 14:30:41 +0000378 }
379
380 DC = D->getLexicalDeclContext();
381 }
Argyrios Kyrtzidis951f61f2013-03-08 20:42:33 +0000382
383 return false;
Guy Benyei11169dd2012-12-18 14:30:41 +0000384}
385
386bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
387 if (!AU->getPreprocessor().getPreprocessingRecord())
388 return false;
389
390 PreprocessingRecord &PPRec
391 = *AU->getPreprocessor().getPreprocessingRecord();
392 SourceManager &SM = AU->getSourceManager();
393
394 if (RegionOfInterest.isValid()) {
395 SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
396 SourceLocation B = MappedRange.getBegin();
397 SourceLocation E = MappedRange.getEnd();
398
399 if (AU->isInPreambleFileID(B)) {
400 if (SM.isLoadedSourceLocation(E))
401 return visitPreprocessedEntitiesInRange(SourceRange(B, E),
402 PPRec, *this);
403
404 // Beginning of range lies in the preamble but it also extends beyond
405 // it into the main file. Split the range into 2 parts, one covering
406 // the preamble and another covering the main file. This allows subsequent
407 // calls to visitPreprocessedEntitiesInRange to accept a source range that
408 // lies in the same FileID, allowing it to skip preprocessed entities that
409 // do not come from the same FileID.
410 bool breaked =
411 visitPreprocessedEntitiesInRange(
412 SourceRange(B, AU->getEndOfPreambleFileID()),
413 PPRec, *this);
414 if (breaked) return true;
415 return visitPreprocessedEntitiesInRange(
416 SourceRange(AU->getStartOfMainFileID(), E),
417 PPRec, *this);
418 }
419
420 return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
421 }
422
423 bool OnlyLocalDecls
424 = !AU->isMainFileAST() && AU->getOnlyLocalDecls();
425
426 if (OnlyLocalDecls)
427 return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
428 PPRec);
429
430 return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
431}
432
433template<typename InputIterator>
434bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
435 InputIterator Last,
436 PreprocessingRecord &PPRec,
437 FileID FID) {
438 for (; First != Last; ++First) {
439 if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
440 continue;
441
442 PreprocessedEntity *PPE = *First;
Argyrios Kyrtzidis1030f262013-05-07 20:37:17 +0000443 if (!PPE)
444 continue;
445
Guy Benyei11169dd2012-12-18 14:30:41 +0000446 if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
447 if (Visit(MakeMacroExpansionCursor(ME, TU)))
448 return true;
449
450 continue;
451 }
452
453 if (MacroDefinition *MD = dyn_cast<MacroDefinition>(PPE)) {
454 if (Visit(MakeMacroDefinitionCursor(MD, TU)))
455 return true;
456
457 continue;
458 }
459
460 if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
461 if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
462 return true;
463
464 continue;
465 }
466 }
467
468 return false;
469}
470
471/// \brief Visit the children of the given cursor.
472///
473/// \returns true if the visitation should be aborted, false if it
474/// should continue.
475bool CursorVisitor::VisitChildren(CXCursor Cursor) {
476 if (clang_isReference(Cursor.kind) &&
477 Cursor.kind != CXCursor_CXXBaseSpecifier) {
478 // By definition, references have no children.
479 return false;
480 }
481
482 // Set the Parent field to Cursor, then back to its old value once we're
483 // done.
484 SetParentRAII SetParent(Parent, StmtParent, Cursor);
485
486 if (clang_isDeclaration(Cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +0000487 Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
Guy Benyei11169dd2012-12-18 14:30:41 +0000488 if (!D)
489 return false;
490
491 return VisitAttributes(D) || Visit(D);
492 }
493
494 if (clang_isStatement(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000495 if (const Stmt *S = getCursorStmt(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000496 return Visit(S);
497
498 return false;
499 }
500
501 if (clang_isExpression(Cursor.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +0000502 if (const Expr *E = getCursorExpr(Cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +0000503 return Visit(E);
504
505 return false;
506 }
507
508 if (clang_isTranslationUnit(Cursor.kind)) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000509 CXTranslationUnit TU = getCursorTU(Cursor);
510 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +0000511
512 int VisitOrder[2] = { VisitPreprocessorLast, !VisitPreprocessorLast };
513 for (unsigned I = 0; I != 2; ++I) {
514 if (VisitOrder[I]) {
515 if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
516 RegionOfInterest.isInvalid()) {
517 for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
518 TLEnd = CXXUnit->top_level_end();
519 TL != TLEnd; ++TL) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +0000520 if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000521 return true;
522 }
523 } else if (VisitDeclContext(
524 CXXUnit->getASTContext().getTranslationUnitDecl()))
525 return true;
526 continue;
527 }
528
529 // Walk the preprocessing record.
530 if (CXXUnit->getPreprocessor().getPreprocessingRecord())
531 visitPreprocessedEntitiesInRegion();
532 }
533
534 return false;
535 }
536
537 if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000538 if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000539 if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
540 return Visit(BaseTSInfo->getTypeLoc());
541 }
542 }
543 }
544
545 if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +0000546 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +0000547 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
Richard Smithb1f9a282013-10-31 01:56:18 +0000548 if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
Richard Smithb87c4652013-10-31 21:23:20 +0000549 return Visit(cxcursor::MakeCursorObjCClassRef(
550 ObjT->getInterface(),
551 A->getInterfaceLoc()->getTypeLoc().getLocStart(), TU));
Guy Benyei11169dd2012-12-18 14:30:41 +0000552 }
553
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000554 // If pointing inside a macro definition, check if the token is an identifier
555 // that was ever defined as a macro. In such a case, create a "pseudo" macro
556 // expansion cursor for that token.
557 SourceLocation BeginLoc = RegionOfInterest.getBegin();
558 if (Cursor.kind == CXCursor_MacroDefinition &&
559 BeginLoc == RegionOfInterest.getEnd()) {
560 SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +0000561 const MacroInfo *MI =
562 getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +0000563 if (MacroDefinition *MacroDef =
564 checkForMacroInMacroDefinition(MI, Loc, TU))
565 return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
566 }
567
Guy Benyei11169dd2012-12-18 14:30:41 +0000568 // Nothing to visit at the moment.
569 return false;
570}
571
572bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
573 if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
574 if (Visit(TSInfo->getTypeLoc()))
575 return true;
576
577 if (Stmt *Body = B->getBody())
578 return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));
579
580 return false;
581}
582
Ted Kremenek03325582013-02-21 01:29:01 +0000583Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
Guy Benyei11169dd2012-12-18 14:30:41 +0000584 if (RegionOfInterest.isValid()) {
585 SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
586 if (Range.isInvalid())
David Blaikie7a30dc52013-02-21 01:47:18 +0000587 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000588
589 switch (CompareRegionOfInterest(Range)) {
590 case RangeBefore:
591 // This declaration comes before the region of interest; skip it.
David Blaikie7a30dc52013-02-21 01:47:18 +0000592 return None;
Guy Benyei11169dd2012-12-18 14:30:41 +0000593
594 case RangeAfter:
595 // This declaration comes after the region of interest; we're done.
596 return false;
597
598 case RangeOverlap:
599 // This declaration overlaps the region of interest; visit it.
600 break;
601 }
602 }
603 return true;
604}
605
606bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
607 DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
608
609 // FIXME: Eventually remove. This part of a hack to support proper
610 // iteration over all Decls contained lexically within an ObjC container.
611 SaveAndRestore<DeclContext::decl_iterator*> DI_saved(DI_current, &I);
612 SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);
613
614 for ( ; I != E; ++I) {
615 Decl *D = *I;
616 if (D->getLexicalDeclContext() != DC)
617 continue;
618 CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
619
620 // Ignore synthesized ivars here, otherwise if we have something like:
621 // @synthesize prop = _prop;
622 // and '_prop' is not declared, we will encounter a '_prop' ivar before
623 // encountering the 'prop' synthesize declaration and we will think that
624 // we passed the region-of-interest.
625 if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
626 if (ivarD->getSynthesize())
627 continue;
628 }
629
630 // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
631 // declarations is a mismatch with the compiler semantics.
632 if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
633 ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
634 if (!ID->isThisDeclarationADefinition())
635 Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
636
637 } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
638 ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
639 if (!PD->isThisDeclarationADefinition())
640 Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
641 }
642
Ted Kremenek03325582013-02-21 01:29:01 +0000643 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +0000644 if (!V.hasValue())
645 continue;
646 if (!V.getValue())
647 return false;
648 if (Visit(Cursor, true))
649 return true;
650 }
651 return false;
652}
653
654bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
655 llvm_unreachable("Translation units are visited directly by Visit()");
656}
657
658bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
659 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
660 return Visit(TSInfo->getTypeLoc());
661
662 return false;
663}
664
665bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
666 if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
667 return Visit(TSInfo->getTypeLoc());
668
669 return false;
670}
671
672bool CursorVisitor::VisitTagDecl(TagDecl *D) {
673 return VisitDeclContext(D);
674}
675
676bool CursorVisitor::VisitClassTemplateSpecializationDecl(
677 ClassTemplateSpecializationDecl *D) {
678 bool ShouldVisitBody = false;
679 switch (D->getSpecializationKind()) {
680 case TSK_Undeclared:
681 case TSK_ImplicitInstantiation:
682 // Nothing to visit
683 return false;
684
685 case TSK_ExplicitInstantiationDeclaration:
686 case TSK_ExplicitInstantiationDefinition:
687 break;
688
689 case TSK_ExplicitSpecialization:
690 ShouldVisitBody = true;
691 break;
692 }
693
694 // Visit the template arguments used in the specialization.
695 if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
696 TypeLoc TL = SpecType->getTypeLoc();
David Blaikie6adc78e2013-02-18 22:06:02 +0000697 if (TemplateSpecializationTypeLoc TSTLoc =
698 TL.getAs<TemplateSpecializationTypeLoc>()) {
699 for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
700 if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000701 return true;
702 }
703 }
704
705 if (ShouldVisitBody && VisitCXXRecordDecl(D))
706 return true;
707
708 return false;
709}
710
711bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
712 ClassTemplatePartialSpecializationDecl *D) {
713 // FIXME: Visit the "outer" template parameter lists on the TagDecl
714 // before visiting these template parameters.
715 if (VisitTemplateParameters(D->getTemplateParameters()))
716 return true;
717
718 // Visit the partial specialization arguments.
Enea Zaffanella6dbe1872013-08-10 07:24:53 +0000719 const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
720 const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
721 for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
Guy Benyei11169dd2012-12-18 14:30:41 +0000722 if (VisitTemplateArgumentLoc(TemplateArgs[I]))
723 return true;
724
725 return VisitCXXRecordDecl(D);
726}
727
728bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
729 // Visit the default argument.
730 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
731 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
732 if (Visit(DefArg->getTypeLoc()))
733 return true;
734
735 return false;
736}
737
738bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
739 if (Expr *Init = D->getInitExpr())
740 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
741 return false;
742}
743
744bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000745 unsigned NumParamList = DD->getNumTemplateParameterLists();
746 for (unsigned i = 0; i < NumParamList; i++) {
747 TemplateParameterList* Params = DD->getTemplateParameterList(i);
748 if (VisitTemplateParameters(Params))
749 return true;
750 }
751
Guy Benyei11169dd2012-12-18 14:30:41 +0000752 if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
753 if (Visit(TSInfo->getTypeLoc()))
754 return true;
755
756 // Visit the nested-name-specifier, if present.
757 if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
758 if (VisitNestedNameSpecifierLoc(QualifierLoc))
759 return true;
760
761 return false;
762}
763
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000764/// \brief Compare two base or member initializers based on their source order.
765static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
766 CXXCtorInitializer *const *Y) {
767 return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
768}
769
Guy Benyei11169dd2012-12-18 14:30:41 +0000770bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
Argyrios Kyrtzidis2ec76742013-04-05 21:04:10 +0000771 unsigned NumParamList = ND->getNumTemplateParameterLists();
772 for (unsigned i = 0; i < NumParamList; i++) {
773 TemplateParameterList* Params = ND->getTemplateParameterList(i);
774 if (VisitTemplateParameters(Params))
775 return true;
776 }
777
Guy Benyei11169dd2012-12-18 14:30:41 +0000778 if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
779 // Visit the function declaration's syntactic components in the order
780 // written. This requires a bit of work.
781 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
David Blaikie6adc78e2013-02-18 22:06:02 +0000782 FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
Guy Benyei11169dd2012-12-18 14:30:41 +0000783
784 // If we have a function declared directly (without the use of a typedef),
785 // visit just the return type. Otherwise, just visit the function's type
786 // now.
Alp Toker42a16a62014-01-25 23:51:36 +0000787 if ((FTL && !isa<CXXConversionDecl>(ND) && Visit(FTL.getReturnLoc())) ||
Guy Benyei11169dd2012-12-18 14:30:41 +0000788 (!FTL && Visit(TL)))
789 return true;
790
791 // Visit the nested-name-specifier, if present.
792 if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
793 if (VisitNestedNameSpecifierLoc(QualifierLoc))
794 return true;
795
796 // Visit the declaration name.
Argyrios Kyrtzidis4a4d2b42014-02-09 08:13:47 +0000797 if (!isa<CXXDestructorDecl>(ND))
798 if (VisitDeclarationNameInfo(ND->getNameInfo()))
799 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +0000800
801 // FIXME: Visit explicitly-specified template arguments!
802
803 // Visit the function parameters, if we have a function type.
David Blaikie6adc78e2013-02-18 22:06:02 +0000804 if (FTL && VisitFunctionTypeLoc(FTL, true))
Guy Benyei11169dd2012-12-18 14:30:41 +0000805 return true;
806
Bill Wendling44426052012-12-20 19:22:21 +0000807 // FIXME: Attributes?
Guy Benyei11169dd2012-12-18 14:30:41 +0000808 }
809
810 if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
811 if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
812 // Find the initializers that were written in the source.
813 SmallVector<CXXCtorInitializer *, 4> WrittenInits;
Aaron Ballman0ad78302014-03-13 17:34:31 +0000814 for (auto *I : Constructor->inits()) {
815 if (!I->isWritten())
Guy Benyei11169dd2012-12-18 14:30:41 +0000816 continue;
817
Aaron Ballman0ad78302014-03-13 17:34:31 +0000818 WrittenInits.push_back(I);
Guy Benyei11169dd2012-12-18 14:30:41 +0000819 }
820
821 // Sort the initializers in source order
Benjamin Kramer4cadf292014-03-07 21:51:58 +0000822 llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
823 &CompareCXXCtorInitializers);
824
Guy Benyei11169dd2012-12-18 14:30:41 +0000825 // Visit the initializers in source order
826 for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
827 CXXCtorInitializer *Init = WrittenInits[I];
828 if (Init->isAnyMemberInitializer()) {
829 if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
830 Init->getMemberLocation(), TU)))
831 return true;
832 } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
833 if (Visit(TInfo->getTypeLoc()))
834 return true;
835 }
836
837 // Visit the initializer value.
838 if (Expr *Initializer = Init->getInit())
839 if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
840 return true;
841 }
842 }
843
844 if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
845 return true;
846 }
847
848 return false;
849}
850
851bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
852 if (VisitDeclaratorDecl(D))
853 return true;
854
855 if (Expr *BitWidth = D->getBitWidth())
856 return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));
857
858 return false;
859}
860
861bool CursorVisitor::VisitVarDecl(VarDecl *D) {
862 if (VisitDeclaratorDecl(D))
863 return true;
864
865 if (Expr *Init = D->getInit())
866 return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
867
868 return false;
869}
870
871bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
872 if (VisitDeclaratorDecl(D))
873 return true;
874
875 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
876 if (Expr *DefArg = D->getDefaultArgument())
877 return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));
878
879 return false;
880}
881
882bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
883 // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
884 // before visiting these template parameters.
885 if (VisitTemplateParameters(D->getTemplateParameters()))
886 return true;
887
888 return VisitFunctionDecl(D->getTemplatedDecl());
889}
890
891bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
892 // FIXME: Visit the "outer" template parameter lists on the TagDecl
893 // before visiting these template parameters.
894 if (VisitTemplateParameters(D->getTemplateParameters()))
895 return true;
896
897 return VisitCXXRecordDecl(D->getTemplatedDecl());
898}
899
900bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
901 if (VisitTemplateParameters(D->getTemplateParameters()))
902 return true;
903
904 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
905 VisitTemplateArgumentLoc(D->getDefaultArgument()))
906 return true;
907
908 return false;
909}
910
911bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
Alp Toker314cc812014-01-25 16:55:45 +0000912 if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
Guy Benyei11169dd2012-12-18 14:30:41 +0000913 if (Visit(TSInfo->getTypeLoc()))
914 return true;
915
Aaron Ballman43b68be2014-03-07 17:50:17 +0000916 for (const auto *P : ND->params()) {
917 if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
Guy Benyei11169dd2012-12-18 14:30:41 +0000918 return true;
919 }
920
921 if (ND->isThisDeclarationADefinition() &&
922 Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
923 return true;
924
925 return false;
926}
927
928template <typename DeclIt>
929static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
930 SourceManager &SM, SourceLocation EndLoc,
931 SmallVectorImpl<Decl *> &Decls) {
932 DeclIt next = *DI_current;
933 while (++next != DE_current) {
934 Decl *D_next = *next;
935 if (!D_next)
936 break;
937 SourceLocation L = D_next->getLocStart();
938 if (!L.isValid())
939 break;
940 if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
941 *DI_current = next;
942 Decls.push_back(D_next);
943 continue;
944 }
945 break;
946 }
947}
948
Guy Benyei11169dd2012-12-18 14:30:41 +0000949bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
950 // FIXME: Eventually convert back to just 'VisitDeclContext()'. Essentially
951 // an @implementation can lexically contain Decls that are not properly
952 // nested in the AST. When we identify such cases, we need to retrofit
953 // this nesting here.
954 if (!DI_current && !FileDI_current)
955 return VisitDeclContext(D);
956
957 // Scan the Decls that immediately come after the container
958 // in the current DeclContext. If any fall within the
959 // container's lexical region, stash them into a vector
960 // for later processing.
961 SmallVector<Decl *, 24> DeclsInContainer;
962 SourceLocation EndLoc = D->getSourceRange().getEnd();
963 SourceManager &SM = AU->getSourceManager();
964 if (EndLoc.isValid()) {
965 if (DI_current) {
966 addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
967 DeclsInContainer);
968 } else {
969 addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
970 DeclsInContainer);
971 }
972 }
973
974 // The common case.
975 if (DeclsInContainer.empty())
976 return VisitDeclContext(D);
977
978 // Get all the Decls in the DeclContext, and sort them with the
979 // additional ones we've collected. Then visit them.
Aaron Ballman629afae2014-03-07 19:56:05 +0000980 for (auto *SubDecl : D->decls()) {
981 if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
982 SubDecl->getLocStart().isInvalid())
Guy Benyei11169dd2012-12-18 14:30:41 +0000983 continue;
Aaron Ballman629afae2014-03-07 19:56:05 +0000984 DeclsInContainer.push_back(SubDecl);
Guy Benyei11169dd2012-12-18 14:30:41 +0000985 }
986
987 // Now sort the Decls so that they appear in lexical order.
988 std::sort(DeclsInContainer.begin(), DeclsInContainer.end(),
Benjamin Kramerbbdd7642014-03-01 14:48:57 +0000989 [&SM](Decl *A, Decl *B) {
990 SourceLocation L_A = A->getLocStart();
991 SourceLocation L_B = B->getLocStart();
992 assert(L_A.isValid() && L_B.isValid());
993 return SM.isBeforeInTranslationUnit(L_A, L_B);
994 });
Guy Benyei11169dd2012-12-18 14:30:41 +0000995
996 // Now visit the decls.
997 for (SmallVectorImpl<Decl*>::iterator I = DeclsInContainer.begin(),
998 E = DeclsInContainer.end(); I != E; ++I) {
999 CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
Ted Kremenek03325582013-02-21 01:29:01 +00001000 const Optional<bool> &V = shouldVisitCursor(Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00001001 if (!V.hasValue())
1002 continue;
1003 if (!V.getValue())
1004 return false;
1005 if (Visit(Cursor, true))
1006 return true;
1007 }
1008 return false;
1009}
1010
1011bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
1012 if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
1013 TU)))
1014 return true;
1015
1016 ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
1017 for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
1018 E = ND->protocol_end(); I != E; ++I, ++PL)
1019 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1020 return true;
1021
1022 return VisitObjCContainerDecl(ND);
1023}
1024
1025bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1026 if (!PID->isThisDeclarationADefinition())
1027 return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));
1028
1029 ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
1030 for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
1031 E = PID->protocol_end(); I != E; ++I, ++PL)
1032 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1033 return true;
1034
1035 return VisitObjCContainerDecl(PID);
1036}
1037
1038bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
1039 if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
1040 return true;
1041
1042 // FIXME: This implements a workaround with @property declarations also being
1043 // installed in the DeclContext for the @interface. Eventually this code
1044 // should be removed.
1045 ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
1046 if (!CDecl || !CDecl->IsClassExtension())
1047 return false;
1048
1049 ObjCInterfaceDecl *ID = CDecl->getClassInterface();
1050 if (!ID)
1051 return false;
1052
1053 IdentifierInfo *PropertyId = PD->getIdentifier();
1054 ObjCPropertyDecl *prevDecl =
1055 ObjCPropertyDecl::findPropertyDecl(cast<DeclContext>(ID), PropertyId);
1056
1057 if (!prevDecl)
1058 return false;
1059
1060 // Visit synthesized methods since they will be skipped when visiting
1061 // the @interface.
1062 if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
1063 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1064 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1065 return true;
1066
1067 if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
1068 if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
1069 if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
1070 return true;
1071
1072 return false;
1073}
1074
1075bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
1076 if (!D->isThisDeclarationADefinition()) {
1077 // Forward declaration is treated like a reference.
1078 return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
1079 }
1080
1081 // Issue callbacks for super class.
1082 if (D->getSuperClass() &&
1083 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1084 D->getSuperClassLoc(),
1085 TU)))
1086 return true;
1087
1088 ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
1089 for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
1090 E = D->protocol_end(); I != E; ++I, ++PL)
1091 if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
1092 return true;
1093
1094 return VisitObjCContainerDecl(D);
1095}
1096
1097bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
1098 return VisitObjCContainerDecl(D);
1099}
1100
1101bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
1102 // 'ID' could be null when dealing with invalid code.
1103 if (ObjCInterfaceDecl *ID = D->getClassInterface())
1104 if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
1105 return true;
1106
1107 return VisitObjCImplDecl(D);
1108}
1109
1110bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
1111#if 0
1112 // Issue callbacks for super class.
1113 // FIXME: No source location information!
1114 if (D->getSuperClass() &&
1115 Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
1116 D->getSuperClassLoc(),
1117 TU)))
1118 return true;
1119#endif
1120
1121 return VisitObjCImplDecl(D);
1122}
1123
1124bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
1125 if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
1126 if (PD->isIvarNameSpecified())
1127 return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));
1128
1129 return false;
1130}
1131
1132bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
1133 return VisitDeclContext(D);
1134}
1135
1136bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1137 // Visit nested-name-specifier.
1138 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1139 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1140 return true;
1141
1142 return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
1143 D->getTargetNameLoc(), TU));
1144}
1145
1146bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
1147 // Visit nested-name-specifier.
1148 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1149 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1150 return true;
1151 }
1152
1153 if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
1154 return true;
1155
1156 return VisitDeclarationNameInfo(D->getNameInfo());
1157}
1158
1159bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1160 // Visit nested-name-specifier.
1161 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1162 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1163 return true;
1164
1165 return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
1166 D->getIdentLocation(), TU));
1167}
1168
1169bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1170 // Visit nested-name-specifier.
1171 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
1172 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1173 return true;
1174 }
1175
1176 return VisitDeclarationNameInfo(D->getNameInfo());
1177}
1178
1179bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
1180 UnresolvedUsingTypenameDecl *D) {
1181 // Visit nested-name-specifier.
1182 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1183 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1184 return true;
1185
1186 return false;
1187}
1188
1189bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
1190 switch (Name.getName().getNameKind()) {
1191 case clang::DeclarationName::Identifier:
1192 case clang::DeclarationName::CXXLiteralOperatorName:
1193 case clang::DeclarationName::CXXOperatorName:
1194 case clang::DeclarationName::CXXUsingDirective:
1195 return false;
1196
1197 case clang::DeclarationName::CXXConstructorName:
1198 case clang::DeclarationName::CXXDestructorName:
1199 case clang::DeclarationName::CXXConversionFunctionName:
1200 if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
1201 return Visit(TSInfo->getTypeLoc());
1202 return false;
1203
1204 case clang::DeclarationName::ObjCZeroArgSelector:
1205 case clang::DeclarationName::ObjCOneArgSelector:
1206 case clang::DeclarationName::ObjCMultiArgSelector:
1207 // FIXME: Per-identifier location info?
1208 return false;
1209 }
1210
1211 llvm_unreachable("Invalid DeclarationName::Kind!");
1212}
1213
1214bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
1215 SourceRange Range) {
1216 // FIXME: This whole routine is a hack to work around the lack of proper
1217 // source information in nested-name-specifiers (PR5791). Since we do have
1218 // a beginning source location, we can visit the first component of the
1219 // nested-name-specifier, if it's a single-token component.
1220 if (!NNS)
1221 return false;
1222
1223 // Get the first component in the nested-name-specifier.
1224 while (NestedNameSpecifier *Prefix = NNS->getPrefix())
1225 NNS = Prefix;
1226
1227 switch (NNS->getKind()) {
1228 case NestedNameSpecifier::Namespace:
1229 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(),
1230 TU));
1231
1232 case NestedNameSpecifier::NamespaceAlias:
1233 return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1234 Range.getBegin(), TU));
1235
1236 case NestedNameSpecifier::TypeSpec: {
1237 // If the type has a form where we know that the beginning of the source
1238 // range matches up with a reference cursor. Visit the appropriate reference
1239 // cursor.
1240 const Type *T = NNS->getAsType();
1241 if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
1242 return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
1243 if (const TagType *Tag = dyn_cast<TagType>(T))
1244 return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
1245 if (const TemplateSpecializationType *TST
1246 = dyn_cast<TemplateSpecializationType>(T))
1247 return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
1248 break;
1249 }
1250
1251 case NestedNameSpecifier::TypeSpecWithTemplate:
1252 case NestedNameSpecifier::Global:
1253 case NestedNameSpecifier::Identifier:
1254 break;
1255 }
1256
1257 return false;
1258}
1259
1260bool
1261CursorVisitor::VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1262 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
1263 for (; Qualifier; Qualifier = Qualifier.getPrefix())
1264 Qualifiers.push_back(Qualifier);
1265
1266 while (!Qualifiers.empty()) {
1267 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
1268 NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
1269 switch (NNS->getKind()) {
1270 case NestedNameSpecifier::Namespace:
1271 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
1272 Q.getLocalBeginLoc(),
1273 TU)))
1274 return true;
1275
1276 break;
1277
1278 case NestedNameSpecifier::NamespaceAlias:
1279 if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
1280 Q.getLocalBeginLoc(),
1281 TU)))
1282 return true;
1283
1284 break;
1285
1286 case NestedNameSpecifier::TypeSpec:
1287 case NestedNameSpecifier::TypeSpecWithTemplate:
1288 if (Visit(Q.getTypeLoc()))
1289 return true;
1290
1291 break;
1292
1293 case NestedNameSpecifier::Global:
1294 case NestedNameSpecifier::Identifier:
1295 break;
1296 }
1297 }
1298
1299 return false;
1300}
1301
1302bool CursorVisitor::VisitTemplateParameters(
1303 const TemplateParameterList *Params) {
1304 if (!Params)
1305 return false;
1306
1307 for (TemplateParameterList::const_iterator P = Params->begin(),
1308 PEnd = Params->end();
1309 P != PEnd; ++P) {
1310 if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
1311 return true;
1312 }
1313
1314 return false;
1315}
1316
1317bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
1318 switch (Name.getKind()) {
1319 case TemplateName::Template:
1320 return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
1321
1322 case TemplateName::OverloadedTemplate:
1323 // Visit the overloaded template set.
1324 if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
1325 return true;
1326
1327 return false;
1328
1329 case TemplateName::DependentTemplate:
1330 // FIXME: Visit nested-name-specifier.
1331 return false;
1332
1333 case TemplateName::QualifiedTemplate:
1334 // FIXME: Visit nested-name-specifier.
1335 return Visit(MakeCursorTemplateRef(
1336 Name.getAsQualifiedTemplateName()->getDecl(),
1337 Loc, TU));
1338
1339 case TemplateName::SubstTemplateTemplateParm:
1340 return Visit(MakeCursorTemplateRef(
1341 Name.getAsSubstTemplateTemplateParm()->getParameter(),
1342 Loc, TU));
1343
1344 case TemplateName::SubstTemplateTemplateParmPack:
1345 return Visit(MakeCursorTemplateRef(
1346 Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(),
1347 Loc, TU));
1348 }
1349
1350 llvm_unreachable("Invalid TemplateName::Kind!");
1351}
1352
1353bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
1354 switch (TAL.getArgument().getKind()) {
1355 case TemplateArgument::Null:
1356 case TemplateArgument::Integral:
1357 case TemplateArgument::Pack:
1358 return false;
1359
1360 case TemplateArgument::Type:
1361 if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
1362 return Visit(TSInfo->getTypeLoc());
1363 return false;
1364
1365 case TemplateArgument::Declaration:
1366 if (Expr *E = TAL.getSourceDeclExpression())
1367 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1368 return false;
1369
1370 case TemplateArgument::NullPtr:
1371 if (Expr *E = TAL.getSourceNullPtrExpression())
1372 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1373 return false;
1374
1375 case TemplateArgument::Expression:
1376 if (Expr *E = TAL.getSourceExpression())
1377 return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
1378 return false;
1379
1380 case TemplateArgument::Template:
1381 case TemplateArgument::TemplateExpansion:
1382 if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
1383 return true;
1384
1385 return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
1386 TAL.getTemplateNameLoc());
1387 }
1388
1389 llvm_unreachable("Invalid TemplateArgument::Kind!");
1390}
1391
1392bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1393 return VisitDeclContext(D);
1394}
1395
1396bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
1397 return Visit(TL.getUnqualifiedLoc());
1398}
1399
1400bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
1401 ASTContext &Context = AU->getASTContext();
1402
1403 // Some builtin types (such as Objective-C's "id", "sel", and
1404 // "Class") have associated declarations. Create cursors for those.
1405 QualType VisitType;
1406 switch (TL.getTypePtr()->getKind()) {
1407
1408 case BuiltinType::Void:
1409 case BuiltinType::NullPtr:
1410 case BuiltinType::Dependent:
Guy Benyeid8a08ea2012-12-18 14:38:23 +00001411 case BuiltinType::OCLImage1d:
1412 case BuiltinType::OCLImage1dArray:
1413 case BuiltinType::OCLImage1dBuffer:
1414 case BuiltinType::OCLImage2d:
1415 case BuiltinType::OCLImage2dArray:
1416 case BuiltinType::OCLImage3d:
NAKAMURA Takumi288c42e2013-02-07 12:47:42 +00001417 case BuiltinType::OCLSampler:
Guy Benyei1b4fb3e2013-01-20 12:31:11 +00001418 case BuiltinType::OCLEvent:
Guy Benyei11169dd2012-12-18 14:30:41 +00001419#define BUILTIN_TYPE(Id, SingletonId)
1420#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1421#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
1422#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
1423#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
1424#include "clang/AST/BuiltinTypes.def"
1425 break;
1426
1427 case BuiltinType::ObjCId:
1428 VisitType = Context.getObjCIdType();
1429 break;
1430
1431 case BuiltinType::ObjCClass:
1432 VisitType = Context.getObjCClassType();
1433 break;
1434
1435 case BuiltinType::ObjCSel:
1436 VisitType = Context.getObjCSelType();
1437 break;
1438 }
1439
1440 if (!VisitType.isNull()) {
1441 if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
1442 return Visit(MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(),
1443 TU));
1444 }
1445
1446 return false;
1447}
1448
1449bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
1450 return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
1451}
1452
1453bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
1454 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1455}
1456
1457bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
1458 if (TL.isDefinition())
1459 return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
1460
1461 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1462}
1463
1464bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
1465 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1466}
1467
1468bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
1469 if (Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU)))
1470 return true;
1471
1472 return false;
1473}
1474
1475bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
1476 if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
1477 return true;
1478
1479 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1480 if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
1481 TU)))
1482 return true;
1483 }
1484
1485 return false;
1486}
1487
1488bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
1489 return Visit(TL.getPointeeLoc());
1490}
1491
1492bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
1493 return Visit(TL.getInnerLoc());
1494}
1495
1496bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
1497 return Visit(TL.getPointeeLoc());
1498}
1499
1500bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
1501 return Visit(TL.getPointeeLoc());
1502}
1503
1504bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
1505 return Visit(TL.getPointeeLoc());
1506}
1507
1508bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
1509 return Visit(TL.getPointeeLoc());
1510}
1511
1512bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
1513 return Visit(TL.getPointeeLoc());
1514}
1515
1516bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
1517 return Visit(TL.getModifiedLoc());
1518}
1519
1520bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
1521 bool SkipResultType) {
Alp Toker42a16a62014-01-25 23:51:36 +00001522 if (!SkipResultType && Visit(TL.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00001523 return true;
1524
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00001525 for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
1526 if (Decl *D = TL.getParam(I))
Guy Benyei11169dd2012-12-18 14:30:41 +00001527 if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
1528 return true;
1529
1530 return false;
1531}
1532
1533bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
1534 if (Visit(TL.getElementLoc()))
1535 return true;
1536
1537 if (Expr *Size = TL.getSizeExpr())
1538 return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));
1539
1540 return false;
1541}
1542
Reid Kleckner8a365022013-06-24 17:51:48 +00001543bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
1544 return Visit(TL.getOriginalLoc());
1545}
1546
Reid Kleckner0503a872013-12-05 01:23:43 +00001547bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
1548 return Visit(TL.getOriginalLoc());
1549}
1550
Guy Benyei11169dd2012-12-18 14:30:41 +00001551bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
1552 TemplateSpecializationTypeLoc TL) {
1553 // Visit the template name.
1554 if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
1555 TL.getTemplateNameLoc()))
1556 return true;
1557
1558 // Visit the template arguments.
1559 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1560 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1561 return true;
1562
1563 return false;
1564}
1565
1566bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
1567 return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
1568}
1569
1570bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
1571 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1572 return Visit(TSInfo->getTypeLoc());
1573
1574 return false;
1575}
1576
1577bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
1578 if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
1579 return Visit(TSInfo->getTypeLoc());
1580
1581 return false;
1582}
1583
1584bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
1585 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1586 return true;
1587
1588 return false;
1589}
1590
1591bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
1592 DependentTemplateSpecializationTypeLoc TL) {
1593 // Visit the nested-name-specifier, if there is one.
1594 if (TL.getQualifierLoc() &&
1595 VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1596 return true;
1597
1598 // Visit the template arguments.
1599 for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
1600 if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
1601 return true;
1602
1603 return false;
1604}
1605
1606bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
1607 if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
1608 return true;
1609
1610 return Visit(TL.getNamedTypeLoc());
1611}
1612
1613bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
1614 return Visit(TL.getPatternLoc());
1615}
1616
1617bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
1618 if (Expr *E = TL.getUnderlyingExpr())
1619 return Visit(MakeCXCursor(E, StmtParent, TU));
1620
1621 return false;
1622}
1623
1624bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
1625 return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
1626}
1627
1628bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
1629 return Visit(TL.getValueLoc());
1630}
1631
1632#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
1633bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
1634 return Visit##PARENT##Loc(TL); \
1635}
1636
1637DEFAULT_TYPELOC_IMPL(Complex, Type)
1638DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
1639DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
1640DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
1641DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
1642DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
1643DEFAULT_TYPELOC_IMPL(Vector, Type)
1644DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
1645DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
1646DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
1647DEFAULT_TYPELOC_IMPL(Record, TagType)
1648DEFAULT_TYPELOC_IMPL(Enum, TagType)
1649DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
1650DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
1651DEFAULT_TYPELOC_IMPL(Auto, Type)
1652
1653bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
1654 // Visit the nested-name-specifier, if present.
1655 if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
1656 if (VisitNestedNameSpecifierLoc(QualifierLoc))
1657 return true;
1658
1659 if (D->isCompleteDefinition()) {
Aaron Ballman574705e2014-03-13 15:41:46 +00001660 for (const auto &I : D->bases()) {
1661 if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001662 return true;
1663 }
1664 }
1665
1666 return VisitTagDecl(D);
1667}
1668
1669bool CursorVisitor::VisitAttributes(Decl *D) {
Aaron Ballmanb97112e2014-03-08 22:19:01 +00001670 for (const auto *I : D->attrs())
1671 if (Visit(MakeCXCursor(I, D, TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00001672 return true;
1673
1674 return false;
1675}
1676
1677//===----------------------------------------------------------------------===//
1678// Data-recursive visitor methods.
1679//===----------------------------------------------------------------------===//
1680
1681namespace {
1682#define DEF_JOB(NAME, DATA, KIND)\
1683class NAME : public VisitorJob {\
1684public:\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001685 NAME(const DATA *d, CXCursor parent) : \
1686 VisitorJob(parent, VisitorJob::KIND, d) {} \
Guy Benyei11169dd2012-12-18 14:30:41 +00001687 static bool classof(const VisitorJob *VJ) { return VJ->getKind() == KIND; }\
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001688 const DATA *get() const { return static_cast<const DATA*>(data[0]); }\
Guy Benyei11169dd2012-12-18 14:30:41 +00001689};
1690
1691DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
1692DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
1693DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
1694DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
1695DEF_JOB(ExplicitTemplateArgsVisit, ASTTemplateArgumentListInfo,
1696 ExplicitTemplateArgsVisitKind)
1697DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
1698DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
1699DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
1700#undef DEF_JOB
1701
1702class DeclVisit : public VisitorJob {
1703public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001704 DeclVisit(const Decl *D, CXCursor parent, bool isFirst) :
Guy Benyei11169dd2012-12-18 14:30:41 +00001705 VisitorJob(parent, VisitorJob::DeclVisitKind,
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001706 D, isFirst ? (void*) 1 : (void*) 0) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001707 static bool classof(const VisitorJob *VJ) {
1708 return VJ->getKind() == DeclVisitKind;
1709 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001710 const Decl *get() const { return static_cast<const Decl *>(data[0]); }
Guy Benyei11169dd2012-12-18 14:30:41 +00001711 bool isFirst() const { return data[1] ? true : false; }
1712};
1713class TypeLocVisit : public VisitorJob {
1714public:
1715 TypeLocVisit(TypeLoc tl, CXCursor parent) :
1716 VisitorJob(parent, VisitorJob::TypeLocVisitKind,
1717 tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}
1718
1719 static bool classof(const VisitorJob *VJ) {
1720 return VJ->getKind() == TypeLocVisitKind;
1721 }
1722
1723 TypeLoc get() const {
1724 QualType T = QualType::getFromOpaquePtr(data[0]);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001725 return TypeLoc(T, const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001726 }
1727};
1728
1729class LabelRefVisit : public VisitorJob {
1730public:
1731 LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
1732 : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
1733 labelLoc.getPtrEncoding()) {}
1734
1735 static bool classof(const VisitorJob *VJ) {
1736 return VJ->getKind() == VisitorJob::LabelRefVisitKind;
1737 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001738 const LabelDecl *get() const {
1739 return static_cast<const LabelDecl *>(data[0]);
1740 }
Guy Benyei11169dd2012-12-18 14:30:41 +00001741 SourceLocation getLoc() const {
1742 return SourceLocation::getFromPtrEncoding(data[1]); }
1743};
1744
1745class NestedNameSpecifierLocVisit : public VisitorJob {
1746public:
1747 NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
1748 : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
1749 Qualifier.getNestedNameSpecifier(),
1750 Qualifier.getOpaqueData()) { }
1751
1752 static bool classof(const VisitorJob *VJ) {
1753 return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
1754 }
1755
1756 NestedNameSpecifierLoc get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001757 return NestedNameSpecifierLoc(
1758 const_cast<NestedNameSpecifier *>(
1759 static_cast<const NestedNameSpecifier *>(data[0])),
1760 const_cast<void *>(data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00001761 }
1762};
1763
1764class DeclarationNameInfoVisit : public VisitorJob {
1765public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001766 DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
Dmitri Gribenkodd7dacf2013-02-03 13:19:54 +00001767 : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
Guy Benyei11169dd2012-12-18 14:30:41 +00001768 static bool classof(const VisitorJob *VJ) {
1769 return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
1770 }
1771 DeclarationNameInfo get() const {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001772 const Stmt *S = static_cast<const Stmt *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001773 switch (S->getStmtClass()) {
1774 default:
1775 llvm_unreachable("Unhandled Stmt");
1776 case clang::Stmt::MSDependentExistsStmtClass:
1777 return cast<MSDependentExistsStmt>(S)->getNameInfo();
1778 case Stmt::CXXDependentScopeMemberExprClass:
1779 return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
1780 case Stmt::DependentScopeDeclRefExprClass:
1781 return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
1782 }
1783 }
1784};
1785class MemberRefVisit : public VisitorJob {
1786public:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001787 MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
Guy Benyei11169dd2012-12-18 14:30:41 +00001788 : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
1789 L.getPtrEncoding()) {}
1790 static bool classof(const VisitorJob *VJ) {
1791 return VJ->getKind() == VisitorJob::MemberRefVisitKind;
1792 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001793 const FieldDecl *get() const {
1794 return static_cast<const FieldDecl *>(data[0]);
Guy Benyei11169dd2012-12-18 14:30:41 +00001795 }
1796 SourceLocation getLoc() const {
1797 return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t) data[1]);
1798 }
1799};
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001800class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001801 friend class OMPClauseEnqueue;
Guy Benyei11169dd2012-12-18 14:30:41 +00001802 VisitorWorkList &WL;
1803 CXCursor Parent;
1804public:
1805 EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
1806 : WL(wl), Parent(parent) {}
1807
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001808 void VisitAddrLabelExpr(const AddrLabelExpr *E);
1809 void VisitBlockExpr(const BlockExpr *B);
1810 void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
1811 void VisitCompoundStmt(const CompoundStmt *S);
1812 void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */ }
1813 void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
1814 void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
1815 void VisitCXXNewExpr(const CXXNewExpr *E);
1816 void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
1817 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
1818 void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
1819 void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
1820 void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
1821 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
1822 void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
1823 void VisitCXXCatchStmt(const CXXCatchStmt *S);
1824 void VisitDeclRefExpr(const DeclRefExpr *D);
1825 void VisitDeclStmt(const DeclStmt *S);
1826 void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
1827 void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
1828 void VisitExplicitCastExpr(const ExplicitCastExpr *E);
1829 void VisitForStmt(const ForStmt *FS);
1830 void VisitGotoStmt(const GotoStmt *GS);
1831 void VisitIfStmt(const IfStmt *If);
1832 void VisitInitListExpr(const InitListExpr *IE);
1833 void VisitMemberExpr(const MemberExpr *M);
1834 void VisitOffsetOfExpr(const OffsetOfExpr *E);
1835 void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
1836 void VisitObjCMessageExpr(const ObjCMessageExpr *M);
1837 void VisitOverloadExpr(const OverloadExpr *E);
1838 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
1839 void VisitStmt(const Stmt *S);
1840 void VisitSwitchStmt(const SwitchStmt *S);
1841 void VisitWhileStmt(const WhileStmt *W);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001842 void VisitTypeTraitExpr(const TypeTraitExpr *E);
1843 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
1844 void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
1845 void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
1846 void VisitVAArgExpr(const VAArgExpr *E);
1847 void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
1848 void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
1849 void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
1850 void VisitLambdaExpr(const LambdaExpr *E);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001851 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
1852 void VisitOMPParallelDirective(const OMPParallelDirective *D);
Alexey Bataev1b59ab52014-02-27 08:29:12 +00001853 void VisitOMPSimdDirective(const OMPSimdDirective *D);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001854
Guy Benyei11169dd2012-12-18 14:30:41 +00001855private:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001856 void AddDeclarationNameInfo(const Stmt *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001857 void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
1858 void AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001859 void AddMemberRef(const FieldDecl *D, SourceLocation L);
1860 void AddStmt(const Stmt *S);
1861 void AddDecl(const Decl *D, bool isFirst = true);
Guy Benyei11169dd2012-12-18 14:30:41 +00001862 void AddTypeLoc(TypeSourceInfo *TI);
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001863 void EnqueueChildren(const Stmt *S);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001864 void EnqueueChildren(const OMPClause *S);
Guy Benyei11169dd2012-12-18 14:30:41 +00001865};
1866} // end anonyous namespace
1867
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001868void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001869 // 'S' should always be non-null, since it comes from the
1870 // statement we are visiting.
1871 WL.push_back(DeclarationNameInfoVisit(S, Parent));
1872}
1873
1874void
1875EnqueueVisitor::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier) {
1876 if (Qualifier)
1877 WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
1878}
1879
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001880void EnqueueVisitor::AddStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001881 if (S)
1882 WL.push_back(StmtVisit(S, Parent));
1883}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001884void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001885 if (D)
1886 WL.push_back(DeclVisit(D, Parent, isFirst));
1887}
1888void EnqueueVisitor::
1889 AddExplicitTemplateArgs(const ASTTemplateArgumentListInfo *A) {
1890 if (A)
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001891 WL.push_back(ExplicitTemplateArgsVisit(A, Parent));
Guy Benyei11169dd2012-12-18 14:30:41 +00001892}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001893void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001894 if (D)
1895 WL.push_back(MemberRefVisit(D, L, Parent));
1896}
1897void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
1898 if (TI)
1899 WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
1900 }
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001901void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001902 unsigned size = WL.size();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001903 for (Stmt::const_child_range Child = S->children(); Child; ++Child) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001904 AddStmt(*Child);
1905 }
1906 if (size == WL.size())
1907 return;
1908 // Now reverse the entries we just added. This will match the DFS
1909 // ordering performed by the worklist.
1910 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1911 std::reverse(I, E);
1912}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001913namespace {
1914class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
1915 EnqueueVisitor *Visitor;
Alexey Bataev756c1962013-09-24 03:17:45 +00001916 /// \brief Process clauses with list of variables.
1917 template <typename T>
1918 void VisitOMPClauseList(T *Node);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001919public:
1920 OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) { }
1921#define OPENMP_CLAUSE(Name, Class) \
1922 void Visit##Class(const Class *C);
1923#include "clang/Basic/OpenMPKinds.def"
1924};
1925
Alexey Bataevaadd52e2014-02-13 05:29:23 +00001926void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
1927 Visitor->AddStmt(C->getCondition());
1928}
1929
Alexey Bataev568a8332014-03-06 06:15:19 +00001930void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
1931 Visitor->AddStmt(C->getNumThreads());
1932}
1933
Alexey Bataev62c87d22014-03-21 04:51:18 +00001934void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
1935 Visitor->AddStmt(C->getSafelen());
1936}
1937
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001938void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001939
1940template<typename T>
1941void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001942 for (const auto *I : Node->varlists())
1943 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001944}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001945
1946void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001947 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001948}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001949void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1950 const OMPFirstprivateClause *C) {
1951 VisitOMPClauseList(C);
1952}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001953void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001954 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001955}
Alexander Musman8dba6642014-04-22 13:09:42 +00001956void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
1957 VisitOMPClauseList(C);
1958 Visitor->AddStmt(C->getStep());
1959}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00001960void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
1961 VisitOMPClauseList(C);
1962}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001963}
Alexey Bataev756c1962013-09-24 03:17:45 +00001964
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001965void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1966 unsigned size = WL.size();
1967 OMPClauseEnqueue Visitor(this);
1968 Visitor.Visit(S);
1969 if (size == WL.size())
1970 return;
1971 // Now reverse the entries we just added. This will match the DFS
1972 // ordering performed by the worklist.
1973 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1974 std::reverse(I, E);
1975}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001976void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001977 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1978}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001979void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001980 AddDecl(B->getBlockDecl());
1981}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001982void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001983 EnqueueChildren(E);
1984 AddTypeLoc(E->getTypeSourceInfo());
1985}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001986void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1987 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001988 E = S->body_rend(); I != E; ++I) {
1989 AddStmt(*I);
1990 }
1991}
1992void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001993VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001994 AddStmt(S->getSubStmt());
1995 AddDeclarationNameInfo(S);
1996 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
1997 AddNestedNameSpecifierLoc(QualifierLoc);
1998}
1999
2000void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002001VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002002 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2003 AddDeclarationNameInfo(E);
2004 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2005 AddNestedNameSpecifierLoc(QualifierLoc);
2006 if (!E->isImplicitAccess())
2007 AddStmt(E->getBase());
2008}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002009void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002010 // Enqueue the initializer , if any.
2011 AddStmt(E->getInitializer());
2012 // Enqueue the array size, if any.
2013 AddStmt(E->getArraySize());
2014 // Enqueue the allocated type.
2015 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2016 // Enqueue the placement arguments.
2017 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2018 AddStmt(E->getPlacementArg(I-1));
2019}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002020void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002021 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2022 AddStmt(CE->getArg(I-1));
2023 AddStmt(CE->getCallee());
2024 AddStmt(CE->getArg(0));
2025}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002026void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2027 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002028 // Visit the name of the type being destroyed.
2029 AddTypeLoc(E->getDestroyedTypeInfo());
2030 // Visit the scope type that looks disturbingly like the nested-name-specifier
2031 // but isn't.
2032 AddTypeLoc(E->getScopeTypeInfo());
2033 // Visit the nested-name-specifier.
2034 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2035 AddNestedNameSpecifierLoc(QualifierLoc);
2036 // Visit base expression.
2037 AddStmt(E->getBase());
2038}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002039void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2040 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002041 AddTypeLoc(E->getTypeSourceInfo());
2042}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002043void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2044 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002045 EnqueueChildren(E);
2046 AddTypeLoc(E->getTypeSourceInfo());
2047}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002048void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002049 EnqueueChildren(E);
2050 if (E->isTypeOperand())
2051 AddTypeLoc(E->getTypeOperandSourceInfo());
2052}
2053
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002054void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2055 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002056 EnqueueChildren(E);
2057 AddTypeLoc(E->getTypeSourceInfo());
2058}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002059void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002060 EnqueueChildren(E);
2061 if (E->isTypeOperand())
2062 AddTypeLoc(E->getTypeOperandSourceInfo());
2063}
2064
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002065void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002066 EnqueueChildren(S);
2067 AddDecl(S->getExceptionDecl());
2068}
2069
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002070void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002071 if (DR->hasExplicitTemplateArgs()) {
2072 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2073 }
2074 WL.push_back(DeclRefExprParts(DR, Parent));
2075}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002076void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2077 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002078 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2079 AddDeclarationNameInfo(E);
2080 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2081}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002082void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002083 unsigned size = WL.size();
2084 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002085 for (const auto *D : S->decls()) {
2086 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002087 isFirst = false;
2088 }
2089 if (size == WL.size())
2090 return;
2091 // Now reverse the entries we just added. This will match the DFS
2092 // ordering performed by the worklist.
2093 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2094 std::reverse(I, E);
2095}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002096void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002097 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002098 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002099 D = E->designators_rbegin(), DEnd = E->designators_rend();
2100 D != DEnd; ++D) {
2101 if (D->isFieldDesignator()) {
2102 if (FieldDecl *Field = D->getField())
2103 AddMemberRef(Field, D->getFieldLoc());
2104 continue;
2105 }
2106 if (D->isArrayDesignator()) {
2107 AddStmt(E->getArrayIndex(*D));
2108 continue;
2109 }
2110 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2111 AddStmt(E->getArrayRangeEnd(*D));
2112 AddStmt(E->getArrayRangeStart(*D));
2113 }
2114}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002115void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002116 EnqueueChildren(E);
2117 AddTypeLoc(E->getTypeInfoAsWritten());
2118}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002119void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002120 AddStmt(FS->getBody());
2121 AddStmt(FS->getInc());
2122 AddStmt(FS->getCond());
2123 AddDecl(FS->getConditionVariable());
2124 AddStmt(FS->getInit());
2125}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002126void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002127 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2128}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002129void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002130 AddStmt(If->getElse());
2131 AddStmt(If->getThen());
2132 AddStmt(If->getCond());
2133 AddDecl(If->getConditionVariable());
2134}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002135void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002136 // We care about the syntactic form of the initializer list, only.
2137 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2138 IE = Syntactic;
2139 EnqueueChildren(IE);
2140}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002141void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002142 WL.push_back(MemberExprParts(M, Parent));
2143
2144 // If the base of the member access expression is an implicit 'this', don't
2145 // visit it.
2146 // FIXME: If we ever want to show these implicit accesses, this will be
2147 // unfortunate. However, clang_getCursor() relies on this behavior.
2148 if (!M->isImplicitAccess())
2149 AddStmt(M->getBase());
2150}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002151void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002152 AddTypeLoc(E->getEncodedTypeSourceInfo());
2153}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002154void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002155 EnqueueChildren(M);
2156 AddTypeLoc(M->getClassReceiverTypeInfo());
2157}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002158void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002159 // Visit the components of the offsetof expression.
2160 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2161 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2162 const OffsetOfNode &Node = E->getComponent(I-1);
2163 switch (Node.getKind()) {
2164 case OffsetOfNode::Array:
2165 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2166 break;
2167 case OffsetOfNode::Field:
2168 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2169 break;
2170 case OffsetOfNode::Identifier:
2171 case OffsetOfNode::Base:
2172 continue;
2173 }
2174 }
2175 // Visit the type into which we're computing the offset.
2176 AddTypeLoc(E->getTypeSourceInfo());
2177}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002178void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002179 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2180 WL.push_back(OverloadExprParts(E, Parent));
2181}
2182void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002183 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002184 EnqueueChildren(E);
2185 if (E->isArgumentType())
2186 AddTypeLoc(E->getArgumentTypeInfo());
2187}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002188void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002189 EnqueueChildren(S);
2190}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002191void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002192 AddStmt(S->getBody());
2193 AddStmt(S->getCond());
2194 AddDecl(S->getConditionVariable());
2195}
2196
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002197void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002198 AddStmt(W->getBody());
2199 AddStmt(W->getCond());
2200 AddDecl(W->getConditionVariable());
2201}
2202
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002203void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002204 for (unsigned I = E->getNumArgs(); I > 0; --I)
2205 AddTypeLoc(E->getArg(I-1));
2206}
2207
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002208void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002209 AddTypeLoc(E->getQueriedTypeSourceInfo());
2210}
2211
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002212void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002213 EnqueueChildren(E);
2214}
2215
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002216void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002217 VisitOverloadExpr(U);
2218 if (!U->isImplicitAccess())
2219 AddStmt(U->getBase());
2220}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002221void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002222 AddStmt(E->getSubExpr());
2223 AddTypeLoc(E->getWrittenTypeInfo());
2224}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002225void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002226 WL.push_back(SizeOfPackExprParts(E, Parent));
2227}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002228void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002229 // If the opaque value has a source expression, just transparently
2230 // visit that. This is useful for (e.g.) pseudo-object expressions.
2231 if (Expr *SourceExpr = E->getSourceExpr())
2232 return Visit(SourceExpr);
2233}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002234void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002235 AddStmt(E->getBody());
2236 WL.push_back(LambdaExprParts(E, Parent));
2237}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002238void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002239 // Treat the expression like its syntactic form.
2240 Visit(E->getSyntacticForm());
2241}
2242
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002243void EnqueueVisitor::VisitOMPExecutableDirective(
2244 const OMPExecutableDirective *D) {
2245 EnqueueChildren(D);
2246 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2247 E = D->clauses().end();
2248 I != E; ++I)
2249 EnqueueChildren(*I);
2250}
2251
2252void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2253 VisitOMPExecutableDirective(D);
2254}
2255
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002256void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2257 VisitOMPExecutableDirective(D);
2258}
2259
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002260void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002261 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2262}
2263
2264bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2265 if (RegionOfInterest.isValid()) {
2266 SourceRange Range = getRawCursorExtent(C);
2267 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2268 return false;
2269 }
2270 return true;
2271}
2272
2273bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2274 while (!WL.empty()) {
2275 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002276 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002277
2278 // Set the Parent field, then back to its old value once we're done.
2279 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2280
2281 switch (LI.getKind()) {
2282 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002283 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002284 if (!D)
2285 continue;
2286
2287 // For now, perform default visitation for Decls.
2288 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2289 cast<DeclVisit>(&LI)->isFirst())))
2290 return true;
2291
2292 continue;
2293 }
2294 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2295 const ASTTemplateArgumentListInfo *ArgList =
2296 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2297 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2298 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2299 Arg != ArgEnd; ++Arg) {
2300 if (VisitTemplateArgumentLoc(*Arg))
2301 return true;
2302 }
2303 continue;
2304 }
2305 case VisitorJob::TypeLocVisitKind: {
2306 // Perform default visitation for TypeLocs.
2307 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2308 return true;
2309 continue;
2310 }
2311 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002312 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002313 if (LabelStmt *stmt = LS->getStmt()) {
2314 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2315 TU))) {
2316 return true;
2317 }
2318 }
2319 continue;
2320 }
2321
2322 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2323 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2324 if (VisitNestedNameSpecifierLoc(V->get()))
2325 return true;
2326 continue;
2327 }
2328
2329 case VisitorJob::DeclarationNameInfoVisitKind: {
2330 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2331 ->get()))
2332 return true;
2333 continue;
2334 }
2335 case VisitorJob::MemberRefVisitKind: {
2336 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2337 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2338 return true;
2339 continue;
2340 }
2341 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002342 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002343 if (!S)
2344 continue;
2345
2346 // Update the current cursor.
2347 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2348 if (!IsInRegionOfInterest(Cursor))
2349 continue;
2350 switch (Visitor(Cursor, Parent, ClientData)) {
2351 case CXChildVisit_Break: return true;
2352 case CXChildVisit_Continue: break;
2353 case CXChildVisit_Recurse:
2354 if (PostChildrenVisitor)
2355 WL.push_back(PostChildrenVisit(0, Cursor));
2356 EnqueueWorkList(WL, S);
2357 break;
2358 }
2359 continue;
2360 }
2361 case VisitorJob::MemberExprPartsKind: {
2362 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002363 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002364
2365 // Visit the nested-name-specifier
2366 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2367 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2368 return true;
2369
2370 // Visit the declaration name.
2371 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2372 return true;
2373
2374 // Visit the explicitly-specified template arguments, if any.
2375 if (M->hasExplicitTemplateArgs()) {
2376 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2377 *ArgEnd = Arg + M->getNumTemplateArgs();
2378 Arg != ArgEnd; ++Arg) {
2379 if (VisitTemplateArgumentLoc(*Arg))
2380 return true;
2381 }
2382 }
2383 continue;
2384 }
2385 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002386 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002387 // Visit nested-name-specifier, if present.
2388 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2389 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2390 return true;
2391 // Visit declaration name.
2392 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2393 return true;
2394 continue;
2395 }
2396 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002397 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002398 // Visit the nested-name-specifier.
2399 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2400 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2401 return true;
2402 // Visit the declaration name.
2403 if (VisitDeclarationNameInfo(O->getNameInfo()))
2404 return true;
2405 // Visit the overloaded declaration reference.
2406 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2407 return true;
2408 continue;
2409 }
2410 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002411 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002412 NamedDecl *Pack = E->getPack();
2413 if (isa<TemplateTypeParmDecl>(Pack)) {
2414 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2415 E->getPackLoc(), TU)))
2416 return true;
2417
2418 continue;
2419 }
2420
2421 if (isa<TemplateTemplateParmDecl>(Pack)) {
2422 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2423 E->getPackLoc(), TU)))
2424 return true;
2425
2426 continue;
2427 }
2428
2429 // Non-type template parameter packs and function parameter packs are
2430 // treated like DeclRefExpr cursors.
2431 continue;
2432 }
2433
2434 case VisitorJob::LambdaExprPartsKind: {
2435 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002436 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002437 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2438 CEnd = E->explicit_capture_end();
2439 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002440 // FIXME: Lambda init-captures.
2441 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002442 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002443
Guy Benyei11169dd2012-12-18 14:30:41 +00002444 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2445 C->getLocation(),
2446 TU)))
2447 return true;
2448 }
2449
2450 // Visit parameters and return type, if present.
2451 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2452 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2453 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2454 // Visit the whole type.
2455 if (Visit(TL))
2456 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002457 } else if (FunctionProtoTypeLoc Proto =
2458 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002459 if (E->hasExplicitParameters()) {
2460 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002461 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2462 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002463 return true;
2464 } else {
2465 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002466 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002467 return true;
2468 }
2469 }
2470 }
2471 break;
2472 }
2473
2474 case VisitorJob::PostChildrenVisitKind:
2475 if (PostChildrenVisitor(Parent, ClientData))
2476 return true;
2477 break;
2478 }
2479 }
2480 return false;
2481}
2482
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002483bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002484 VisitorWorkList *WL = 0;
2485 if (!WorkListFreeList.empty()) {
2486 WL = WorkListFreeList.back();
2487 WL->clear();
2488 WorkListFreeList.pop_back();
2489 }
2490 else {
2491 WL = new VisitorWorkList();
2492 WorkListCache.push_back(WL);
2493 }
2494 EnqueueWorkList(*WL, S);
2495 bool result = RunVisitorWorkList(*WL);
2496 WorkListFreeList.push_back(WL);
2497 return result;
2498}
2499
2500namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002501typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002502RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2503 const DeclarationNameInfo &NI,
2504 const SourceRange &QLoc,
2505 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2506 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2507 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2508 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2509
2510 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2511
2512 RefNamePieces Pieces;
2513
2514 if (WantQualifier && QLoc.isValid())
2515 Pieces.push_back(QLoc);
2516
2517 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2518 Pieces.push_back(NI.getLoc());
2519
2520 if (WantTemplateArgs && TemplateArgs)
2521 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2522 TemplateArgs->RAngleLoc));
2523
2524 if (Kind == DeclarationName::CXXOperatorName) {
2525 Pieces.push_back(SourceLocation::getFromRawEncoding(
2526 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2527 Pieces.push_back(SourceLocation::getFromRawEncoding(
2528 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2529 }
2530
2531 if (WantSinglePiece) {
2532 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2533 Pieces.clear();
2534 Pieces.push_back(R);
2535 }
2536
2537 return Pieces;
2538}
2539}
2540
2541//===----------------------------------------------------------------------===//
2542// Misc. API hooks.
2543//===----------------------------------------------------------------------===//
2544
2545static llvm::sys::Mutex EnableMultithreadingMutex;
2546static bool EnabledMultithreading;
2547
Chad Rosier05c71aa2013-03-27 18:28:23 +00002548static void fatal_error_handler(void *user_data, const std::string& reason,
2549 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002550 // Write the result out to stderr avoiding errs() because raw_ostreams can
2551 // call report_fatal_error.
2552 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2553 ::abort();
2554}
2555
2556extern "C" {
2557CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2558 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002559 // We use crash recovery to make some of our APIs more reliable, implicitly
2560 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002561 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2562 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002563
2564 // Enable support for multithreading in LLVM.
2565 {
2566 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2567 if (!EnabledMultithreading) {
2568 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2569 llvm::llvm_start_multithreaded();
2570 EnabledMultithreading = true;
2571 }
2572 }
2573
2574 CIndexer *CIdxr = new CIndexer();
2575 if (excludeDeclarationsFromPCH)
2576 CIdxr->setOnlyLocalDecls();
2577 if (displayDiagnostics)
2578 CIdxr->setDisplayDiagnostics();
2579
2580 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2581 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2582 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2583 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2584 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2585 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2586
2587 return CIdxr;
2588}
2589
2590void clang_disposeIndex(CXIndex CIdx) {
2591 if (CIdx)
2592 delete static_cast<CIndexer *>(CIdx);
2593}
2594
2595void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2596 if (CIdx)
2597 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2598}
2599
2600unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2601 if (CIdx)
2602 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2603 return 0;
2604}
2605
2606void clang_toggleCrashRecovery(unsigned isEnabled) {
2607 if (isEnabled)
2608 llvm::CrashRecoveryContext::Enable();
2609 else
2610 llvm::CrashRecoveryContext::Disable();
2611}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002612
Guy Benyei11169dd2012-12-18 14:30:41 +00002613CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2614 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002615 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002616 enum CXErrorCode Result =
2617 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002618 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002619 assert((TU && Result == CXError_Success) ||
2620 (!TU && Result != CXError_Success));
2621 return TU;
2622}
2623
2624enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2625 const char *ast_filename,
2626 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002627 if (out_TU)
2628 *out_TU = NULL;
2629
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002630 if (!CIdx || !ast_filename || !out_TU)
2631 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002632
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002633 LOG_FUNC_SECTION {
2634 *Log << ast_filename;
2635 }
2636
Guy Benyei11169dd2012-12-18 14:30:41 +00002637 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2638 FileSystemOptions FileSystemOpts;
2639
2640 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002641 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002642 CXXIdx->getOnlyLocalDecls(), None,
2643 /*CaptureDiagnostics=*/true,
2644 /*AllowPCHWithCompilerErrors=*/true,
2645 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002646 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2647 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002648}
2649
2650unsigned clang_defaultEditingTranslationUnitOptions() {
2651 return CXTranslationUnit_PrecompiledPreamble |
2652 CXTranslationUnit_CacheCompletionResults;
2653}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002654
Guy Benyei11169dd2012-12-18 14:30:41 +00002655CXTranslationUnit
2656clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2657 const char *source_filename,
2658 int num_command_line_args,
2659 const char * const *command_line_args,
2660 unsigned num_unsaved_files,
2661 struct CXUnsavedFile *unsaved_files) {
2662 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2663 return clang_parseTranslationUnit(CIdx, source_filename,
2664 command_line_args, num_command_line_args,
2665 unsaved_files, num_unsaved_files,
2666 Options);
2667}
2668
2669struct ParseTranslationUnitInfo {
2670 CXIndex CIdx;
2671 const char *source_filename;
2672 const char *const *command_line_args;
2673 int num_command_line_args;
2674 struct CXUnsavedFile *unsaved_files;
2675 unsigned num_unsaved_files;
2676 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002677 CXTranslationUnit *out_TU;
2678 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002679};
2680static void clang_parseTranslationUnit_Impl(void *UserData) {
2681 ParseTranslationUnitInfo *PTUI =
2682 static_cast<ParseTranslationUnitInfo*>(UserData);
2683 CXIndex CIdx = PTUI->CIdx;
2684 const char *source_filename = PTUI->source_filename;
2685 const char * const *command_line_args = PTUI->command_line_args;
2686 int num_command_line_args = PTUI->num_command_line_args;
2687 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2688 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2689 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002690 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002691
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002692 // Set up the initial return values.
2693 if (out_TU)
2694 *out_TU = NULL;
2695 PTUI->result = CXError_Failure;
2696
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002697 // Check arguments.
2698 if (!CIdx || !out_TU ||
2699 (unsaved_files == NULL && num_unsaved_files != 0)) {
2700 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002701 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002702 }
2703
Guy Benyei11169dd2012-12-18 14:30:41 +00002704 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2705
2706 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2707 setThreadBackgroundPriority();
2708
2709 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2710 // FIXME: Add a flag for modules.
2711 TranslationUnitKind TUKind
2712 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002713 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002714 = options & CXTranslationUnit_CacheCompletionResults;
2715 bool IncludeBriefCommentsInCodeCompletion
2716 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2717 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2718 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2719
2720 // Configure the diagnostics.
2721 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002722 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002723
2724 // Recover resources if we crash before exiting this function.
2725 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2726 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2727 DiagCleanup(Diags.getPtr());
2728
Ahmed Charlesb8984322014-03-07 20:03:18 +00002729 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2730 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002731
2732 // Recover resources if we crash before exiting this function.
2733 llvm::CrashRecoveryContextCleanupRegistrar<
2734 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2735
2736 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2737 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2738 const llvm::MemoryBuffer *Buffer
2739 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2740 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2741 Buffer));
2742 }
2743
Ahmed Charlesb8984322014-03-07 20:03:18 +00002744 std::unique_ptr<std::vector<const char *>> Args(
2745 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002746
2747 // Recover resources if we crash before exiting this method.
2748 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2749 ArgsCleanup(Args.get());
2750
2751 // Since the Clang C library is primarily used by batch tools dealing with
2752 // (often very broken) source code, where spell-checking can have a
2753 // significant negative impact on performance (particularly when
2754 // precompiled headers are involved), we disable it by default.
2755 // Only do this if we haven't found a spell-checking-related argument.
2756 bool FoundSpellCheckingArgument = false;
2757 for (int I = 0; I != num_command_line_args; ++I) {
2758 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2759 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2760 FoundSpellCheckingArgument = true;
2761 break;
2762 }
2763 }
2764 if (!FoundSpellCheckingArgument)
2765 Args->push_back("-fno-spell-checking");
2766
2767 Args->insert(Args->end(), command_line_args,
2768 command_line_args + num_command_line_args);
2769
2770 // The 'source_filename' argument is optional. If the caller does not
2771 // specify it then it is assumed that the source file is specified
2772 // in the actual argument list.
2773 // Put the source file after command_line_args otherwise if '-x' flag is
2774 // present it will be unused.
2775 if (source_filename)
2776 Args->push_back(source_filename);
2777
2778 // Do we need the detailed preprocessing record?
2779 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2780 Args->push_back("-Xclang");
2781 Args->push_back("-detailed-preprocessing-record");
2782 }
2783
2784 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002785 std::unique_ptr<ASTUnit> ErrUnit;
2786 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002787 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002788 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2789 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2790 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2791 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2792 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2793 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002794
2795 if (NumErrors != Diags->getClient()->getNumErrors()) {
2796 // Make sure to check that 'Unit' is non-NULL.
2797 if (CXXIdx->getDisplayDiagnostics())
2798 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2799 }
2800
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002801 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2802 PTUI->result = CXError_ASTReadError;
2803 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002804 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002805 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2806 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002807}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002808
2809CXTranslationUnit
2810clang_parseTranslationUnit(CXIndex CIdx,
2811 const char *source_filename,
2812 const char *const *command_line_args,
2813 int num_command_line_args,
2814 struct CXUnsavedFile *unsaved_files,
2815 unsigned num_unsaved_files,
2816 unsigned options) {
2817 CXTranslationUnit TU;
2818 enum CXErrorCode Result = clang_parseTranslationUnit2(
2819 CIdx, source_filename, command_line_args, num_command_line_args,
2820 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002821 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002822 assert((TU && Result == CXError_Success) ||
2823 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002824 return TU;
2825}
2826
2827enum CXErrorCode clang_parseTranslationUnit2(
2828 CXIndex CIdx,
2829 const char *source_filename,
2830 const char *const *command_line_args,
2831 int num_command_line_args,
2832 struct CXUnsavedFile *unsaved_files,
2833 unsigned num_unsaved_files,
2834 unsigned options,
2835 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002836 LOG_FUNC_SECTION {
2837 *Log << source_filename << ": ";
2838 for (int i = 0; i != num_command_line_args; ++i)
2839 *Log << command_line_args[i] << " ";
2840 }
2841
Guy Benyei11169dd2012-12-18 14:30:41 +00002842 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2843 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002844 num_unsaved_files, options, out_TU,
2845 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002846 llvm::CrashRecoveryContext CRC;
2847
2848 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2849 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2850 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2851 fprintf(stderr, " 'command_line_args' : [");
2852 for (int i = 0; i != num_command_line_args; ++i) {
2853 if (i)
2854 fprintf(stderr, ", ");
2855 fprintf(stderr, "'%s'", command_line_args[i]);
2856 }
2857 fprintf(stderr, "],\n");
2858 fprintf(stderr, " 'unsaved_files' : [");
2859 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2860 if (i)
2861 fprintf(stderr, ", ");
2862 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2863 unsaved_files[i].Length);
2864 }
2865 fprintf(stderr, "],\n");
2866 fprintf(stderr, " 'options' : %d,\n", options);
2867 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002868
2869 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002870 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002871 if (CXTranslationUnit *TU = PTUI.out_TU)
2872 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002873 }
2874
2875 return PTUI.result;
2876}
2877
2878unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2879 return CXSaveTranslationUnit_None;
2880}
2881
2882namespace {
2883
2884struct SaveTranslationUnitInfo {
2885 CXTranslationUnit TU;
2886 const char *FileName;
2887 unsigned options;
2888 CXSaveError result;
2889};
2890
2891}
2892
2893static void clang_saveTranslationUnit_Impl(void *UserData) {
2894 SaveTranslationUnitInfo *STUI =
2895 static_cast<SaveTranslationUnitInfo*>(UserData);
2896
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002897 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002898 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2899 setThreadBackgroundPriority();
2900
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002901 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002902 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2903}
2904
2905int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2906 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002907 LOG_FUNC_SECTION {
2908 *Log << TU << ' ' << FileName;
2909 }
2910
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002911 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002912 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002913 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002914 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002915
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002916 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002917 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2918 if (!CXXUnit->hasSema())
2919 return CXSaveError_InvalidTU;
2920
2921 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2922
2923 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2924 getenv("LIBCLANG_NOTHREADS")) {
2925 clang_saveTranslationUnit_Impl(&STUI);
2926
2927 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2928 PrintLibclangResourceUsage(TU);
2929
2930 return STUI.result;
2931 }
2932
2933 // We have an AST that has invalid nodes due to compiler errors.
2934 // Use a crash recovery thread for protection.
2935
2936 llvm::CrashRecoveryContext CRC;
2937
2938 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2939 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2940 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2941 fprintf(stderr, " 'options' : %d,\n", options);
2942 fprintf(stderr, "}\n");
2943
2944 return CXSaveError_Unknown;
2945
2946 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2947 PrintLibclangResourceUsage(TU);
2948 }
2949
2950 return STUI.result;
2951}
2952
2953void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2954 if (CTUnit) {
2955 // If the translation unit has been marked as unsafe to free, just discard
2956 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002957 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2958 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002959 return;
2960
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002961 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002962 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002963 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2964 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002965 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002966 delete CTUnit;
2967 }
2968}
2969
2970unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2971 return CXReparse_None;
2972}
2973
2974struct ReparseTranslationUnitInfo {
2975 CXTranslationUnit TU;
2976 unsigned num_unsaved_files;
2977 struct CXUnsavedFile *unsaved_files;
2978 unsigned options;
2979 int result;
2980};
2981
2982static void clang_reparseTranslationUnit_Impl(void *UserData) {
2983 ReparseTranslationUnitInfo *RTUI =
2984 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002985 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002986
Guy Benyei11169dd2012-12-18 14:30:41 +00002987 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002988 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2989 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
2990 unsigned options = RTUI->options;
2991 (void) options;
2992
2993 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002994 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002995 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002996 RTUI->result = CXError_InvalidArguments;
2997 return;
2998 }
2999 if (unsaved_files == NULL && num_unsaved_files != 0) {
3000 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003001 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003002 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003003
3004 // Reset the associated diagnostics.
3005 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3006 TU->Diagnostics = 0;
3007
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003008 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003009 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3010 setThreadBackgroundPriority();
3011
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003012 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003013 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003014
3015 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3016 new std::vector<ASTUnit::RemappedFile>());
3017
Guy Benyei11169dd2012-12-18 14:30:41 +00003018 // Recover resources if we crash before exiting this function.
3019 llvm::CrashRecoveryContextCleanupRegistrar<
3020 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3021
3022 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3023 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3024 const llvm::MemoryBuffer *Buffer
3025 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3026 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3027 Buffer));
3028 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003029
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003030 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003031 RTUI->result = CXError_Success;
3032 else if (isASTReadError(CXXUnit))
3033 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003034}
3035
3036int clang_reparseTranslationUnit(CXTranslationUnit TU,
3037 unsigned num_unsaved_files,
3038 struct CXUnsavedFile *unsaved_files,
3039 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003040 LOG_FUNC_SECTION {
3041 *Log << TU;
3042 }
3043
Guy Benyei11169dd2012-12-18 14:30:41 +00003044 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003045 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003046
3047 if (getenv("LIBCLANG_NOTHREADS")) {
3048 clang_reparseTranslationUnit_Impl(&RTUI);
3049 return RTUI.result;
3050 }
3051
3052 llvm::CrashRecoveryContext CRC;
3053
3054 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3055 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003056 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003057 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003058 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3059 PrintLibclangResourceUsage(TU);
3060
3061 return RTUI.result;
3062}
3063
3064
3065CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003066 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003067 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003068 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003069 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003070
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003071 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003072 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003073}
3074
3075CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003076 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003077 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003078 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003079 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003080
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003081 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003082 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3083}
3084
3085} // end: extern "C"
3086
3087//===----------------------------------------------------------------------===//
3088// CXFile Operations.
3089//===----------------------------------------------------------------------===//
3090
3091extern "C" {
3092CXString clang_getFileName(CXFile SFile) {
3093 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003094 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003095
3096 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003097 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003098}
3099
3100time_t clang_getFileTime(CXFile SFile) {
3101 if (!SFile)
3102 return 0;
3103
3104 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3105 return FEnt->getModificationTime();
3106}
3107
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003108CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003109 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003110 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003111 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003112 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003113
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003114 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003115
3116 FileManager &FMgr = CXXUnit->getFileManager();
3117 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3118}
3119
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003120unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3121 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003122 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003123 LOG_BAD_TU(TU);
3124 return 0;
3125 }
3126
3127 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003128 return 0;
3129
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003130 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003131 FileEntry *FEnt = static_cast<FileEntry *>(file);
3132 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3133 .isFileMultipleIncludeGuarded(FEnt);
3134}
3135
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003136int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3137 if (!file || !outID)
3138 return 1;
3139
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003140 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003141 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3142 outID->data[0] = ID.getDevice();
3143 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003144 outID->data[2] = FEnt->getModificationTime();
3145 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003146}
3147
Guy Benyei11169dd2012-12-18 14:30:41 +00003148} // end: extern "C"
3149
3150//===----------------------------------------------------------------------===//
3151// CXCursor Operations.
3152//===----------------------------------------------------------------------===//
3153
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003154static const Decl *getDeclFromExpr(const Stmt *E) {
3155 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003156 return getDeclFromExpr(CE->getSubExpr());
3157
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003158 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003159 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003160 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003161 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003162 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003163 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003164 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003165 if (PRE->isExplicitProperty())
3166 return PRE->getExplicitProperty();
3167 // It could be messaging both getter and setter as in:
3168 // ++myobj.myprop;
3169 // in which case prefer to associate the setter since it is less obvious
3170 // from inspecting the source that the setter is going to get called.
3171 if (PRE->isMessagingSetter())
3172 return PRE->getImplicitPropertySetter();
3173 return PRE->getImplicitPropertyGetter();
3174 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003175 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003176 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003177 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003178 if (Expr *Src = OVE->getSourceExpr())
3179 return getDeclFromExpr(Src);
3180
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003181 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003182 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003183 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003184 if (!CE->isElidable())
3185 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003186 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003187 return OME->getMethodDecl();
3188
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003189 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003190 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003191 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003192 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3193 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003194 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003195 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3196 isa<ParmVarDecl>(SizeOfPack->getPack()))
3197 return SizeOfPack->getPack();
3198
3199 return 0;
3200}
3201
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003202static SourceLocation getLocationFromExpr(const Expr *E) {
3203 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003204 return getLocationFromExpr(CE->getSubExpr());
3205
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003206 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003207 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003208 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003209 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003210 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003211 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003212 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003213 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003214 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003215 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003216 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003217 return PropRef->getLocation();
3218
3219 return E->getLocStart();
3220}
3221
3222extern "C" {
3223
3224unsigned clang_visitChildren(CXCursor parent,
3225 CXCursorVisitor visitor,
3226 CXClientData client_data) {
3227 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3228 /*VisitPreprocessorLast=*/false);
3229 return CursorVis.VisitChildren(parent);
3230}
3231
3232#ifndef __has_feature
3233#define __has_feature(x) 0
3234#endif
3235#if __has_feature(blocks)
3236typedef enum CXChildVisitResult
3237 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3238
3239static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3240 CXClientData client_data) {
3241 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3242 return block(cursor, parent);
3243}
3244#else
3245// If we are compiled with a compiler that doesn't have native blocks support,
3246// define and call the block manually, so the
3247typedef struct _CXChildVisitResult
3248{
3249 void *isa;
3250 int flags;
3251 int reserved;
3252 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3253 CXCursor);
3254} *CXCursorVisitorBlock;
3255
3256static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3257 CXClientData client_data) {
3258 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3259 return block->invoke(block, cursor, parent);
3260}
3261#endif
3262
3263
3264unsigned clang_visitChildrenWithBlock(CXCursor parent,
3265 CXCursorVisitorBlock block) {
3266 return clang_visitChildren(parent, visitWithBlock, block);
3267}
3268
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003269static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003270 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003271 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003272
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003273 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003274 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003275 if (const ObjCPropertyImplDecl *PropImpl =
3276 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003277 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003278 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003279
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003280 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003281 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003282 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003283
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003284 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003285 }
3286
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003287 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003288 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003289
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003290 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003291 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3292 // and returns different names. NamedDecl returns the class name and
3293 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003294 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003295
3296 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003297 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003298
3299 SmallString<1024> S;
3300 llvm::raw_svector_ostream os(S);
3301 ND->printName(os);
3302
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003303 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003304}
3305
3306CXString clang_getCursorSpelling(CXCursor C) {
3307 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003308 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003309
3310 if (clang_isReference(C.kind)) {
3311 switch (C.kind) {
3312 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003313 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003314 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003315 }
3316 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003317 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003318 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003319 }
3320 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003321 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003322 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003323 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003324 }
3325 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003326 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003327 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003328 }
3329 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003330 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003331 assert(Type && "Missing type decl");
3332
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003333 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 getAsString());
3335 }
3336 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003337 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 assert(Template && "Missing template decl");
3339
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003340 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003341 }
3342
3343 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003344 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003345 assert(NS && "Missing namespace decl");
3346
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003347 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 }
3349
3350 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003351 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003352 assert(Field && "Missing member decl");
3353
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003354 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003355 }
3356
3357 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003358 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003359 assert(Label && "Missing label");
3360
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003361 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003362 }
3363
3364 case CXCursor_OverloadedDeclRef: {
3365 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003366 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3367 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003368 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003369 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003370 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003371 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003372 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003373 OverloadedTemplateStorage *Ovl
3374 = Storage.get<OverloadedTemplateStorage*>();
3375 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003376 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003377 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003378 }
3379
3380 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003381 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003382 assert(Var && "Missing variable decl");
3383
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003384 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003385 }
3386
3387 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003388 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003389 }
3390 }
3391
3392 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003393 const Expr *E = getCursorExpr(C);
3394
3395 if (C.kind == CXCursor_ObjCStringLiteral ||
3396 C.kind == CXCursor_StringLiteral) {
3397 const StringLiteral *SLit;
3398 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3399 SLit = OSL->getString();
3400 } else {
3401 SLit = cast<StringLiteral>(E);
3402 }
3403 SmallString<256> Buf;
3404 llvm::raw_svector_ostream OS(Buf);
3405 SLit->outputString(OS);
3406 return cxstring::createDup(OS.str());
3407 }
3408
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003409 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003410 if (D)
3411 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003412 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003413 }
3414
3415 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003416 const Stmt *S = getCursorStmt(C);
3417 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003418 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003419
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003420 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003421 }
3422
3423 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003424 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003425 ->getNameStart());
3426
3427 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003428 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003429 ->getNameStart());
3430
3431 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003432 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003433
3434 if (clang_isDeclaration(C.kind))
3435 return getDeclSpelling(getCursorDecl(C));
3436
3437 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003438 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003439 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003440 }
3441
3442 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003443 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003444 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003445 }
3446
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003447 if (C.kind == CXCursor_PackedAttr) {
3448 return cxstring::createRef("packed");
3449 }
3450
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003451 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003452}
3453
3454CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3455 unsigned pieceIndex,
3456 unsigned options) {
3457 if (clang_Cursor_isNull(C))
3458 return clang_getNullRange();
3459
3460 ASTContext &Ctx = getCursorContext(C);
3461
3462 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003463 const Stmt *S = getCursorStmt(C);
3464 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003465 if (pieceIndex > 0)
3466 return clang_getNullRange();
3467 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3468 }
3469
3470 return clang_getNullRange();
3471 }
3472
3473 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003474 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003475 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3476 if (pieceIndex >= ME->getNumSelectorLocs())
3477 return clang_getNullRange();
3478 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3479 }
3480 }
3481
3482 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3483 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003484 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003485 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3486 if (pieceIndex >= MD->getNumSelectorLocs())
3487 return clang_getNullRange();
3488 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3489 }
3490 }
3491
3492 if (C.kind == CXCursor_ObjCCategoryDecl ||
3493 C.kind == CXCursor_ObjCCategoryImplDecl) {
3494 if (pieceIndex > 0)
3495 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003496 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003497 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3498 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003499 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003500 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3501 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3502 }
3503
3504 if (C.kind == CXCursor_ModuleImportDecl) {
3505 if (pieceIndex > 0)
3506 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003507 if (const ImportDecl *ImportD =
3508 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003509 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3510 if (!Locs.empty())
3511 return cxloc::translateSourceRange(Ctx,
3512 SourceRange(Locs.front(), Locs.back()));
3513 }
3514 return clang_getNullRange();
3515 }
3516
3517 // FIXME: A CXCursor_InclusionDirective should give the location of the
3518 // filename, but we don't keep track of this.
3519
3520 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3521 // but we don't keep track of this.
3522
3523 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3524 // but we don't keep track of this.
3525
3526 // Default handling, give the location of the cursor.
3527
3528 if (pieceIndex > 0)
3529 return clang_getNullRange();
3530
3531 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3532 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3533 return cxloc::translateSourceRange(Ctx, Loc);
3534}
3535
3536CXString clang_getCursorDisplayName(CXCursor C) {
3537 if (!clang_isDeclaration(C.kind))
3538 return clang_getCursorSpelling(C);
3539
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003540 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003541 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003542 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003543
3544 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003545 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003546 D = FunTmpl->getTemplatedDecl();
3547
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003548 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003549 SmallString<64> Str;
3550 llvm::raw_svector_ostream OS(Str);
3551 OS << *Function;
3552 if (Function->getPrimaryTemplate())
3553 OS << "<>";
3554 OS << "(";
3555 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3556 if (I)
3557 OS << ", ";
3558 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3559 }
3560
3561 if (Function->isVariadic()) {
3562 if (Function->getNumParams())
3563 OS << ", ";
3564 OS << "...";
3565 }
3566 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003567 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003568 }
3569
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003570 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003571 SmallString<64> Str;
3572 llvm::raw_svector_ostream OS(Str);
3573 OS << *ClassTemplate;
3574 OS << "<";
3575 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3576 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3577 if (I)
3578 OS << ", ";
3579
3580 NamedDecl *Param = Params->getParam(I);
3581 if (Param->getIdentifier()) {
3582 OS << Param->getIdentifier()->getName();
3583 continue;
3584 }
3585
3586 // There is no parameter name, which makes this tricky. Try to come up
3587 // with something useful that isn't too long.
3588 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3589 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3590 else if (NonTypeTemplateParmDecl *NTTP
3591 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3592 OS << NTTP->getType().getAsString(Policy);
3593 else
3594 OS << "template<...> class";
3595 }
3596
3597 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003598 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003599 }
3600
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003601 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003602 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3603 // If the type was explicitly written, use that.
3604 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003605 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003606
Benjamin Kramer9170e912013-02-22 15:46:01 +00003607 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003608 llvm::raw_svector_ostream OS(Str);
3609 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003610 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003611 ClassSpec->getTemplateArgs().data(),
3612 ClassSpec->getTemplateArgs().size(),
3613 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003614 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003615 }
3616
3617 return clang_getCursorSpelling(C);
3618}
3619
3620CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3621 switch (Kind) {
3622 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003623 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003624 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003625 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003626 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003627 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003628 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003629 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003630 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003631 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003632 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003633 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003635 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003637 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003641 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003643 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003645 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003647 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003651 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003653 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003655 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003659 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003663 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003665 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003673 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003750 case CXCursor_ObjCSelfExpr:
3751 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003760 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003761 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003868 case CXCursor_PackedAttr:
3869 return cxstring::createRef("attribute(packed)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003878 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003879 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003880 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003881 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003882 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003883 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003884 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003885 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003886 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003887 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003888 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003889 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003890 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003891 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003892 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003893 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003918 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003919 return cxstring::createRef("OMPParallelDirective");
3920 case CXCursor_OMPSimdDirective:
3921 return cxstring::createRef("OMPSimdDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 }
3923
3924 llvm_unreachable("Unhandled CXCursorKind");
3925}
3926
3927struct GetCursorData {
3928 SourceLocation TokenBeginLoc;
3929 bool PointsAtMacroArgExpansion;
3930 bool VisitedObjCPropertyImplDecl;
3931 SourceLocation VisitedDeclaratorDeclStartLoc;
3932 CXCursor &BestCursor;
3933
3934 GetCursorData(SourceManager &SM,
3935 SourceLocation tokenBegin, CXCursor &outputCursor)
3936 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3937 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3938 VisitedObjCPropertyImplDecl = false;
3939 }
3940};
3941
3942static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3943 CXCursor parent,
3944 CXClientData client_data) {
3945 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3946 CXCursor *BestCursor = &Data->BestCursor;
3947
3948 // If we point inside a macro argument we should provide info of what the
3949 // token is so use the actual cursor, don't replace it with a macro expansion
3950 // cursor.
3951 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3952 return CXChildVisit_Recurse;
3953
3954 if (clang_isDeclaration(cursor.kind)) {
3955 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003956 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003957 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3958 if (MD->isImplicit())
3959 return CXChildVisit_Break;
3960
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003961 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003962 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3963 // Check that when we have multiple @class references in the same line,
3964 // that later ones do not override the previous ones.
3965 // If we have:
3966 // @class Foo, Bar;
3967 // source ranges for both start at '@', so 'Bar' will end up overriding
3968 // 'Foo' even though the cursor location was at 'Foo'.
3969 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3970 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003971 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003972 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3973 if (PrevID != ID &&
3974 !PrevID->isThisDeclarationADefinition() &&
3975 !ID->isThisDeclarationADefinition())
3976 return CXChildVisit_Break;
3977 }
3978
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003979 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00003980 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
3981 SourceLocation StartLoc = DD->getSourceRange().getBegin();
3982 // Check that when we have multiple declarators in the same line,
3983 // that later ones do not override the previous ones.
3984 // If we have:
3985 // int Foo, Bar;
3986 // source ranges for both start at 'int', so 'Bar' will end up overriding
3987 // 'Foo' even though the cursor location was at 'Foo'.
3988 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
3989 return CXChildVisit_Break;
3990 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
3991
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003992 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00003993 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
3994 (void)PropImp;
3995 // Check that when we have multiple @synthesize in the same line,
3996 // that later ones do not override the previous ones.
3997 // If we have:
3998 // @synthesize Foo, Bar;
3999 // source ranges for both start at '@', so 'Bar' will end up overriding
4000 // 'Foo' even though the cursor location was at 'Foo'.
4001 if (Data->VisitedObjCPropertyImplDecl)
4002 return CXChildVisit_Break;
4003 Data->VisitedObjCPropertyImplDecl = true;
4004 }
4005 }
4006
4007 if (clang_isExpression(cursor.kind) &&
4008 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004009 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004010 // Avoid having the cursor of an expression replace the declaration cursor
4011 // when the expression source range overlaps the declaration range.
4012 // This can happen for C++ constructor expressions whose range generally
4013 // include the variable declaration, e.g.:
4014 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4015 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4016 D->getLocation() == Data->TokenBeginLoc)
4017 return CXChildVisit_Break;
4018 }
4019 }
4020
4021 // If our current best cursor is the construction of a temporary object,
4022 // don't replace that cursor with a type reference, because we want
4023 // clang_getCursor() to point at the constructor.
4024 if (clang_isExpression(BestCursor->kind) &&
4025 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4026 cursor.kind == CXCursor_TypeRef) {
4027 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4028 // as having the actual point on the type reference.
4029 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4030 return CXChildVisit_Recurse;
4031 }
4032
4033 *BestCursor = cursor;
4034 return CXChildVisit_Recurse;
4035}
4036
4037CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004038 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004039 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004040 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004041 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004042
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004043 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004044 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4045
4046 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4047 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4048
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004049 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004050 CXFile SearchFile;
4051 unsigned SearchLine, SearchColumn;
4052 CXFile ResultFile;
4053 unsigned ResultLine, ResultColumn;
4054 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4055 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4056 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4057
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004058 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4059 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004060 &ResultColumn, 0);
4061 SearchFileName = clang_getFileName(SearchFile);
4062 ResultFileName = clang_getFileName(ResultFile);
4063 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4064 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004065 *Log << llvm::format("(%s:%d:%d) = %s",
4066 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4067 clang_getCString(KindSpelling))
4068 << llvm::format("(%s:%d:%d):%s%s",
4069 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4070 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004071 clang_disposeString(SearchFileName);
4072 clang_disposeString(ResultFileName);
4073 clang_disposeString(KindSpelling);
4074 clang_disposeString(USR);
4075
4076 CXCursor Definition = clang_getCursorDefinition(Result);
4077 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4078 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4079 CXString DefinitionKindSpelling
4080 = clang_getCursorKindSpelling(Definition.kind);
4081 CXFile DefinitionFile;
4082 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004083 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 &DefinitionLine, &DefinitionColumn, 0);
4085 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004086 *Log << llvm::format(" -> %s(%s:%d:%d)",
4087 clang_getCString(DefinitionKindSpelling),
4088 clang_getCString(DefinitionFileName),
4089 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004090 clang_disposeString(DefinitionFileName);
4091 clang_disposeString(DefinitionKindSpelling);
4092 }
4093 }
4094
4095 return Result;
4096}
4097
4098CXCursor clang_getNullCursor(void) {
4099 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4100}
4101
4102unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004103 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4104 // can't set consistently. For example, when visiting a DeclStmt we will set
4105 // it but we don't set it on the result of clang_getCursorDefinition for
4106 // a reference of the same declaration.
4107 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4108 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4109 // to provide that kind of info.
4110 if (clang_isDeclaration(X.kind))
4111 X.data[1] = 0;
4112 if (clang_isDeclaration(Y.kind))
4113 Y.data[1] = 0;
4114
Guy Benyei11169dd2012-12-18 14:30:41 +00004115 return X == Y;
4116}
4117
4118unsigned clang_hashCursor(CXCursor C) {
4119 unsigned Index = 0;
4120 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4121 Index = 1;
4122
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004123 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004124 std::make_pair(C.kind, C.data[Index]));
4125}
4126
4127unsigned clang_isInvalid(enum CXCursorKind K) {
4128 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4129}
4130
4131unsigned clang_isDeclaration(enum CXCursorKind K) {
4132 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4133 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4134}
4135
4136unsigned clang_isReference(enum CXCursorKind K) {
4137 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4138}
4139
4140unsigned clang_isExpression(enum CXCursorKind K) {
4141 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4142}
4143
4144unsigned clang_isStatement(enum CXCursorKind K) {
4145 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4146}
4147
4148unsigned clang_isAttribute(enum CXCursorKind K) {
4149 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4150}
4151
4152unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4153 return K == CXCursor_TranslationUnit;
4154}
4155
4156unsigned clang_isPreprocessing(enum CXCursorKind K) {
4157 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4158}
4159
4160unsigned clang_isUnexposed(enum CXCursorKind K) {
4161 switch (K) {
4162 case CXCursor_UnexposedDecl:
4163 case CXCursor_UnexposedExpr:
4164 case CXCursor_UnexposedStmt:
4165 case CXCursor_UnexposedAttr:
4166 return true;
4167 default:
4168 return false;
4169 }
4170}
4171
4172CXCursorKind clang_getCursorKind(CXCursor C) {
4173 return C.kind;
4174}
4175
4176CXSourceLocation clang_getCursorLocation(CXCursor C) {
4177 if (clang_isReference(C.kind)) {
4178 switch (C.kind) {
4179 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004180 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004181 = getCursorObjCSuperClassRef(C);
4182 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4183 }
4184
4185 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004186 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004187 = getCursorObjCProtocolRef(C);
4188 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4189 }
4190
4191 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004192 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004193 = getCursorObjCClassRef(C);
4194 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4195 }
4196
4197 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004198 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004199 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4200 }
4201
4202 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004203 std::pair<const TemplateDecl *, SourceLocation> P =
4204 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4206 }
4207
4208 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004209 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004210 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4211 }
4212
4213 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004214 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004215 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4216 }
4217
4218 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004219 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004220 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4221 }
4222
4223 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004224 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004225 if (!BaseSpec)
4226 return clang_getNullLocation();
4227
4228 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4229 return cxloc::translateSourceLocation(getCursorContext(C),
4230 TSInfo->getTypeLoc().getBeginLoc());
4231
4232 return cxloc::translateSourceLocation(getCursorContext(C),
4233 BaseSpec->getLocStart());
4234 }
4235
4236 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004237 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004238 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4239 }
4240
4241 case CXCursor_OverloadedDeclRef:
4242 return cxloc::translateSourceLocation(getCursorContext(C),
4243 getCursorOverloadedDeclRef(C).second);
4244
4245 default:
4246 // FIXME: Need a way to enumerate all non-reference cases.
4247 llvm_unreachable("Missed a reference kind");
4248 }
4249 }
4250
4251 if (clang_isExpression(C.kind))
4252 return cxloc::translateSourceLocation(getCursorContext(C),
4253 getLocationFromExpr(getCursorExpr(C)));
4254
4255 if (clang_isStatement(C.kind))
4256 return cxloc::translateSourceLocation(getCursorContext(C),
4257 getCursorStmt(C)->getLocStart());
4258
4259 if (C.kind == CXCursor_PreprocessingDirective) {
4260 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4261 return cxloc::translateSourceLocation(getCursorContext(C), L);
4262 }
4263
4264 if (C.kind == CXCursor_MacroExpansion) {
4265 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004266 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004267 return cxloc::translateSourceLocation(getCursorContext(C), L);
4268 }
4269
4270 if (C.kind == CXCursor_MacroDefinition) {
4271 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4272 return cxloc::translateSourceLocation(getCursorContext(C), L);
4273 }
4274
4275 if (C.kind == CXCursor_InclusionDirective) {
4276 SourceLocation L
4277 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4278 return cxloc::translateSourceLocation(getCursorContext(C), L);
4279 }
4280
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004281 if (clang_isAttribute(C.kind)) {
4282 SourceLocation L
4283 = cxcursor::getCursorAttr(C)->getLocation();
4284 return cxloc::translateSourceLocation(getCursorContext(C), L);
4285 }
4286
Guy Benyei11169dd2012-12-18 14:30:41 +00004287 if (!clang_isDeclaration(C.kind))
4288 return clang_getNullLocation();
4289
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004290 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004291 if (!D)
4292 return clang_getNullLocation();
4293
4294 SourceLocation Loc = D->getLocation();
4295 // FIXME: Multiple variables declared in a single declaration
4296 // currently lack the information needed to correctly determine their
4297 // ranges when accounting for the type-specifier. We use context
4298 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4299 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004300 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004301 if (!cxcursor::isFirstInDeclGroup(C))
4302 Loc = VD->getLocation();
4303 }
4304
4305 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004306 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004307 Loc = MD->getSelectorStartLoc();
4308
4309 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4310}
4311
4312} // end extern "C"
4313
4314CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4315 assert(TU);
4316
4317 // Guard against an invalid SourceLocation, or we may assert in one
4318 // of the following calls.
4319 if (SLoc.isInvalid())
4320 return clang_getNullCursor();
4321
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004322 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004323
4324 // Translate the given source location to make it point at the beginning of
4325 // the token under the cursor.
4326 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4327 CXXUnit->getASTContext().getLangOpts());
4328
4329 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4330 if (SLoc.isValid()) {
4331 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4332 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4333 /*VisitPreprocessorLast=*/true,
4334 /*VisitIncludedEntities=*/false,
4335 SourceLocation(SLoc));
4336 CursorVis.visitFileRegion();
4337 }
4338
4339 return Result;
4340}
4341
4342static SourceRange getRawCursorExtent(CXCursor C) {
4343 if (clang_isReference(C.kind)) {
4344 switch (C.kind) {
4345 case CXCursor_ObjCSuperClassRef:
4346 return getCursorObjCSuperClassRef(C).second;
4347
4348 case CXCursor_ObjCProtocolRef:
4349 return getCursorObjCProtocolRef(C).second;
4350
4351 case CXCursor_ObjCClassRef:
4352 return getCursorObjCClassRef(C).second;
4353
4354 case CXCursor_TypeRef:
4355 return getCursorTypeRef(C).second;
4356
4357 case CXCursor_TemplateRef:
4358 return getCursorTemplateRef(C).second;
4359
4360 case CXCursor_NamespaceRef:
4361 return getCursorNamespaceRef(C).second;
4362
4363 case CXCursor_MemberRef:
4364 return getCursorMemberRef(C).second;
4365
4366 case CXCursor_CXXBaseSpecifier:
4367 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4368
4369 case CXCursor_LabelRef:
4370 return getCursorLabelRef(C).second;
4371
4372 case CXCursor_OverloadedDeclRef:
4373 return getCursorOverloadedDeclRef(C).second;
4374
4375 case CXCursor_VariableRef:
4376 return getCursorVariableRef(C).second;
4377
4378 default:
4379 // FIXME: Need a way to enumerate all non-reference cases.
4380 llvm_unreachable("Missed a reference kind");
4381 }
4382 }
4383
4384 if (clang_isExpression(C.kind))
4385 return getCursorExpr(C)->getSourceRange();
4386
4387 if (clang_isStatement(C.kind))
4388 return getCursorStmt(C)->getSourceRange();
4389
4390 if (clang_isAttribute(C.kind))
4391 return getCursorAttr(C)->getRange();
4392
4393 if (C.kind == CXCursor_PreprocessingDirective)
4394 return cxcursor::getCursorPreprocessingDirective(C);
4395
4396 if (C.kind == CXCursor_MacroExpansion) {
4397 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004398 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004399 return TU->mapRangeFromPreamble(Range);
4400 }
4401
4402 if (C.kind == CXCursor_MacroDefinition) {
4403 ASTUnit *TU = getCursorASTUnit(C);
4404 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4405 return TU->mapRangeFromPreamble(Range);
4406 }
4407
4408 if (C.kind == CXCursor_InclusionDirective) {
4409 ASTUnit *TU = getCursorASTUnit(C);
4410 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4411 return TU->mapRangeFromPreamble(Range);
4412 }
4413
4414 if (C.kind == CXCursor_TranslationUnit) {
4415 ASTUnit *TU = getCursorASTUnit(C);
4416 FileID MainID = TU->getSourceManager().getMainFileID();
4417 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4418 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4419 return SourceRange(Start, End);
4420 }
4421
4422 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004423 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004424 if (!D)
4425 return SourceRange();
4426
4427 SourceRange R = D->getSourceRange();
4428 // FIXME: Multiple variables declared in a single declaration
4429 // currently lack the information needed to correctly determine their
4430 // ranges when accounting for the type-specifier. We use context
4431 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4432 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004433 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004434 if (!cxcursor::isFirstInDeclGroup(C))
4435 R.setBegin(VD->getLocation());
4436 }
4437 return R;
4438 }
4439 return SourceRange();
4440}
4441
4442/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4443/// the decl-specifier-seq for declarations.
4444static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4445 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004446 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004447 if (!D)
4448 return SourceRange();
4449
4450 SourceRange R = D->getSourceRange();
4451
4452 // Adjust the start of the location for declarations preceded by
4453 // declaration specifiers.
4454 SourceLocation StartLoc;
4455 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4456 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4457 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004458 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004459 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4460 StartLoc = TI->getTypeLoc().getLocStart();
4461 }
4462
4463 if (StartLoc.isValid() && R.getBegin().isValid() &&
4464 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4465 R.setBegin(StartLoc);
4466
4467 // FIXME: Multiple variables declared in a single declaration
4468 // currently lack the information needed to correctly determine their
4469 // ranges when accounting for the type-specifier. We use context
4470 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4471 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004472 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004473 if (!cxcursor::isFirstInDeclGroup(C))
4474 R.setBegin(VD->getLocation());
4475 }
4476
4477 return R;
4478 }
4479
4480 return getRawCursorExtent(C);
4481}
4482
4483extern "C" {
4484
4485CXSourceRange clang_getCursorExtent(CXCursor C) {
4486 SourceRange R = getRawCursorExtent(C);
4487 if (R.isInvalid())
4488 return clang_getNullRange();
4489
4490 return cxloc::translateSourceRange(getCursorContext(C), R);
4491}
4492
4493CXCursor clang_getCursorReferenced(CXCursor C) {
4494 if (clang_isInvalid(C.kind))
4495 return clang_getNullCursor();
4496
4497 CXTranslationUnit tu = getCursorTU(C);
4498 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004499 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004500 if (!D)
4501 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004502 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004503 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004504 if (const ObjCPropertyImplDecl *PropImpl =
4505 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004506 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4507 return MakeCXCursor(Property, tu);
4508
4509 return C;
4510 }
4511
4512 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004513 const Expr *E = getCursorExpr(C);
4514 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004515 if (D) {
4516 CXCursor declCursor = MakeCXCursor(D, tu);
4517 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4518 declCursor);
4519 return declCursor;
4520 }
4521
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004522 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004523 return MakeCursorOverloadedDeclRef(Ovl, tu);
4524
4525 return clang_getNullCursor();
4526 }
4527
4528 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004529 const Stmt *S = getCursorStmt(C);
4530 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004531 if (LabelDecl *label = Goto->getLabel())
4532 if (LabelStmt *labelS = label->getStmt())
4533 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4534
4535 return clang_getNullCursor();
4536 }
4537
4538 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004539 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004540 return MakeMacroDefinitionCursor(Def, tu);
4541 }
4542
4543 if (!clang_isReference(C.kind))
4544 return clang_getNullCursor();
4545
4546 switch (C.kind) {
4547 case CXCursor_ObjCSuperClassRef:
4548 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4549
4550 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004551 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4552 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004553 return MakeCXCursor(Def, tu);
4554
4555 return MakeCXCursor(Prot, tu);
4556 }
4557
4558 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004559 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4560 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004561 return MakeCXCursor(Def, tu);
4562
4563 return MakeCXCursor(Class, tu);
4564 }
4565
4566 case CXCursor_TypeRef:
4567 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4568
4569 case CXCursor_TemplateRef:
4570 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4571
4572 case CXCursor_NamespaceRef:
4573 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4574
4575 case CXCursor_MemberRef:
4576 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4577
4578 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004579 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004580 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4581 tu ));
4582 }
4583
4584 case CXCursor_LabelRef:
4585 // FIXME: We end up faking the "parent" declaration here because we
4586 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004587 return MakeCXCursor(getCursorLabelRef(C).first,
4588 cxtu::getASTUnit(tu)->getASTContext()
4589 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004590 tu);
4591
4592 case CXCursor_OverloadedDeclRef:
4593 return C;
4594
4595 case CXCursor_VariableRef:
4596 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4597
4598 default:
4599 // We would prefer to enumerate all non-reference cursor kinds here.
4600 llvm_unreachable("Unhandled reference cursor kind");
4601 }
4602}
4603
4604CXCursor clang_getCursorDefinition(CXCursor C) {
4605 if (clang_isInvalid(C.kind))
4606 return clang_getNullCursor();
4607
4608 CXTranslationUnit TU = getCursorTU(C);
4609
4610 bool WasReference = false;
4611 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4612 C = clang_getCursorReferenced(C);
4613 WasReference = true;
4614 }
4615
4616 if (C.kind == CXCursor_MacroExpansion)
4617 return clang_getCursorReferenced(C);
4618
4619 if (!clang_isDeclaration(C.kind))
4620 return clang_getNullCursor();
4621
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004622 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004623 if (!D)
4624 return clang_getNullCursor();
4625
4626 switch (D->getKind()) {
4627 // Declaration kinds that don't really separate the notions of
4628 // declaration and definition.
4629 case Decl::Namespace:
4630 case Decl::Typedef:
4631 case Decl::TypeAlias:
4632 case Decl::TypeAliasTemplate:
4633 case Decl::TemplateTypeParm:
4634 case Decl::EnumConstant:
4635 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004636 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004637 case Decl::IndirectField:
4638 case Decl::ObjCIvar:
4639 case Decl::ObjCAtDefsField:
4640 case Decl::ImplicitParam:
4641 case Decl::ParmVar:
4642 case Decl::NonTypeTemplateParm:
4643 case Decl::TemplateTemplateParm:
4644 case Decl::ObjCCategoryImpl:
4645 case Decl::ObjCImplementation:
4646 case Decl::AccessSpec:
4647 case Decl::LinkageSpec:
4648 case Decl::ObjCPropertyImpl:
4649 case Decl::FileScopeAsm:
4650 case Decl::StaticAssert:
4651 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004652 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004653 case Decl::Label: // FIXME: Is this right??
4654 case Decl::ClassScopeFunctionSpecialization:
4655 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004656 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004657 return C;
4658
4659 // Declaration kinds that don't make any sense here, but are
4660 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004661 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004662 case Decl::TranslationUnit:
4663 break;
4664
4665 // Declaration kinds for which the definition is not resolvable.
4666 case Decl::UnresolvedUsingTypename:
4667 case Decl::UnresolvedUsingValue:
4668 break;
4669
4670 case Decl::UsingDirective:
4671 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4672 TU);
4673
4674 case Decl::NamespaceAlias:
4675 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4676
4677 case Decl::Enum:
4678 case Decl::Record:
4679 case Decl::CXXRecord:
4680 case Decl::ClassTemplateSpecialization:
4681 case Decl::ClassTemplatePartialSpecialization:
4682 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4683 return MakeCXCursor(Def, TU);
4684 return clang_getNullCursor();
4685
4686 case Decl::Function:
4687 case Decl::CXXMethod:
4688 case Decl::CXXConstructor:
4689 case Decl::CXXDestructor:
4690 case Decl::CXXConversion: {
4691 const FunctionDecl *Def = 0;
4692 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004693 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004694 return clang_getNullCursor();
4695 }
4696
Larisse Voufo39a1e502013-08-06 01:03:05 +00004697 case Decl::Var:
4698 case Decl::VarTemplateSpecialization:
4699 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004700 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004701 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004702 return MakeCXCursor(Def, TU);
4703 return clang_getNullCursor();
4704 }
4705
4706 case Decl::FunctionTemplate: {
4707 const FunctionDecl *Def = 0;
4708 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4709 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4710 return clang_getNullCursor();
4711 }
4712
4713 case Decl::ClassTemplate: {
4714 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4715 ->getDefinition())
4716 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4717 TU);
4718 return clang_getNullCursor();
4719 }
4720
Larisse Voufo39a1e502013-08-06 01:03:05 +00004721 case Decl::VarTemplate: {
4722 if (VarDecl *Def =
4723 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4724 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4725 return clang_getNullCursor();
4726 }
4727
Guy Benyei11169dd2012-12-18 14:30:41 +00004728 case Decl::Using:
4729 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4730 D->getLocation(), TU);
4731
4732 case Decl::UsingShadow:
4733 return clang_getCursorDefinition(
4734 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4735 TU));
4736
4737 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004738 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004739 if (Method->isThisDeclarationADefinition())
4740 return C;
4741
4742 // Dig out the method definition in the associated
4743 // @implementation, if we have it.
4744 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004745 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004746 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4747 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4748 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4749 Method->isInstanceMethod()))
4750 if (Def->isThisDeclarationADefinition())
4751 return MakeCXCursor(Def, TU);
4752
4753 return clang_getNullCursor();
4754 }
4755
4756 case Decl::ObjCCategory:
4757 if (ObjCCategoryImplDecl *Impl
4758 = cast<ObjCCategoryDecl>(D)->getImplementation())
4759 return MakeCXCursor(Impl, TU);
4760 return clang_getNullCursor();
4761
4762 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004763 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004764 return MakeCXCursor(Def, TU);
4765 return clang_getNullCursor();
4766
4767 case Decl::ObjCInterface: {
4768 // There are two notions of a "definition" for an Objective-C
4769 // class: the interface and its implementation. When we resolved a
4770 // reference to an Objective-C class, produce the @interface as
4771 // the definition; when we were provided with the interface,
4772 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004773 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004774 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004775 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004776 return MakeCXCursor(Def, TU);
4777 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4778 return MakeCXCursor(Impl, TU);
4779 return clang_getNullCursor();
4780 }
4781
4782 case Decl::ObjCProperty:
4783 // FIXME: We don't really know where to find the
4784 // ObjCPropertyImplDecls that implement this property.
4785 return clang_getNullCursor();
4786
4787 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004788 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004789 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004790 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004791 return MakeCXCursor(Def, TU);
4792
4793 return clang_getNullCursor();
4794
4795 case Decl::Friend:
4796 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4797 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4798 return clang_getNullCursor();
4799
4800 case Decl::FriendTemplate:
4801 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4802 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4803 return clang_getNullCursor();
4804 }
4805
4806 return clang_getNullCursor();
4807}
4808
4809unsigned clang_isCursorDefinition(CXCursor C) {
4810 if (!clang_isDeclaration(C.kind))
4811 return 0;
4812
4813 return clang_getCursorDefinition(C) == C;
4814}
4815
4816CXCursor clang_getCanonicalCursor(CXCursor C) {
4817 if (!clang_isDeclaration(C.kind))
4818 return C;
4819
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004820 if (const Decl *D = getCursorDecl(C)) {
4821 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004822 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4823 return MakeCXCursor(CatD, getCursorTU(C));
4824
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004825 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4826 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004827 return MakeCXCursor(IFD, getCursorTU(C));
4828
4829 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4830 }
4831
4832 return C;
4833}
4834
4835int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4836 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4837}
4838
4839unsigned clang_getNumOverloadedDecls(CXCursor C) {
4840 if (C.kind != CXCursor_OverloadedDeclRef)
4841 return 0;
4842
4843 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004844 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004845 return E->getNumDecls();
4846
4847 if (OverloadedTemplateStorage *S
4848 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4849 return S->size();
4850
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004851 const Decl *D = Storage.get<const Decl *>();
4852 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004853 return Using->shadow_size();
4854
4855 return 0;
4856}
4857
4858CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4859 if (cursor.kind != CXCursor_OverloadedDeclRef)
4860 return clang_getNullCursor();
4861
4862 if (index >= clang_getNumOverloadedDecls(cursor))
4863 return clang_getNullCursor();
4864
4865 CXTranslationUnit TU = getCursorTU(cursor);
4866 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004867 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004868 return MakeCXCursor(E->decls_begin()[index], TU);
4869
4870 if (OverloadedTemplateStorage *S
4871 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4872 return MakeCXCursor(S->begin()[index], TU);
4873
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004874 const Decl *D = Storage.get<const Decl *>();
4875 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004876 // FIXME: This is, unfortunately, linear time.
4877 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4878 std::advance(Pos, index);
4879 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4880 }
4881
4882 return clang_getNullCursor();
4883}
4884
4885void clang_getDefinitionSpellingAndExtent(CXCursor C,
4886 const char **startBuf,
4887 const char **endBuf,
4888 unsigned *startLine,
4889 unsigned *startColumn,
4890 unsigned *endLine,
4891 unsigned *endColumn) {
4892 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004893 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004894 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4895
4896 SourceManager &SM = FD->getASTContext().getSourceManager();
4897 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4898 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4899 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4900 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4901 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4902 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4903}
4904
4905
4906CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4907 unsigned PieceIndex) {
4908 RefNamePieces Pieces;
4909
4910 switch (C.kind) {
4911 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004912 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004913 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4914 E->getQualifierLoc().getSourceRange());
4915 break;
4916
4917 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004918 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004919 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4920 E->getQualifierLoc().getSourceRange(),
4921 E->getOptionalExplicitTemplateArgs());
4922 break;
4923
4924 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004925 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004926 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004927 const Expr *Callee = OCE->getCallee();
4928 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004929 Callee = ICE->getSubExpr();
4930
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004931 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004932 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4933 DRE->getQualifierLoc().getSourceRange());
4934 }
4935 break;
4936
4937 default:
4938 break;
4939 }
4940
4941 if (Pieces.empty()) {
4942 if (PieceIndex == 0)
4943 return clang_getCursorExtent(C);
4944 } else if (PieceIndex < Pieces.size()) {
4945 SourceRange R = Pieces[PieceIndex];
4946 if (R.isValid())
4947 return cxloc::translateSourceRange(getCursorContext(C), R);
4948 }
4949
4950 return clang_getNullRange();
4951}
4952
4953void clang_enableStackTraces(void) {
4954 llvm::sys::PrintStackTraceOnErrorSignal();
4955}
4956
4957void clang_executeOnThread(void (*fn)(void*), void *user_data,
4958 unsigned stack_size) {
4959 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4960}
4961
4962} // end: extern "C"
4963
4964//===----------------------------------------------------------------------===//
4965// Token-based Operations.
4966//===----------------------------------------------------------------------===//
4967
4968/* CXToken layout:
4969 * int_data[0]: a CXTokenKind
4970 * int_data[1]: starting token location
4971 * int_data[2]: token length
4972 * int_data[3]: reserved
4973 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4974 * otherwise unused.
4975 */
4976extern "C" {
4977
4978CXTokenKind clang_getTokenKind(CXToken CXTok) {
4979 return static_cast<CXTokenKind>(CXTok.int_data[0]);
4980}
4981
4982CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
4983 switch (clang_getTokenKind(CXTok)) {
4984 case CXToken_Identifier:
4985 case CXToken_Keyword:
4986 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00004987 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00004988 ->getNameStart());
4989
4990 case CXToken_Literal: {
4991 // We have stashed the starting pointer in the ptr_data field. Use it.
4992 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00004993 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00004994 }
4995
4996 case CXToken_Punctuation:
4997 case CXToken_Comment:
4998 break;
4999 }
5000
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005001 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005002 LOG_BAD_TU(TU);
5003 return cxstring::createEmpty();
5004 }
5005
Guy Benyei11169dd2012-12-18 14:30:41 +00005006 // We have to find the starting buffer pointer the hard way, by
5007 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005008 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005009 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005010 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005011
5012 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5013 std::pair<FileID, unsigned> LocInfo
5014 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5015 bool Invalid = false;
5016 StringRef Buffer
5017 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5018 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005019 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005020
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005021 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005022}
5023
5024CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005025 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005026 LOG_BAD_TU(TU);
5027 return clang_getNullLocation();
5028 }
5029
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005030 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005031 if (!CXXUnit)
5032 return clang_getNullLocation();
5033
5034 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5035 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5036}
5037
5038CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005039 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005040 LOG_BAD_TU(TU);
5041 return clang_getNullRange();
5042 }
5043
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005044 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005045 if (!CXXUnit)
5046 return clang_getNullRange();
5047
5048 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5049 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5050}
5051
5052static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5053 SmallVectorImpl<CXToken> &CXTokens) {
5054 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5055 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005056 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005057 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005058 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005059
5060 // Cannot tokenize across files.
5061 if (BeginLocInfo.first != EndLocInfo.first)
5062 return;
5063
5064 // Create a lexer
5065 bool Invalid = false;
5066 StringRef Buffer
5067 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5068 if (Invalid)
5069 return;
5070
5071 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5072 CXXUnit->getASTContext().getLangOpts(),
5073 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5074 Lex.SetCommentRetentionState(true);
5075
5076 // Lex tokens until we hit the end of the range.
5077 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5078 Token Tok;
5079 bool previousWasAt = false;
5080 do {
5081 // Lex the next token
5082 Lex.LexFromRawLexer(Tok);
5083 if (Tok.is(tok::eof))
5084 break;
5085
5086 // Initialize the CXToken.
5087 CXToken CXTok;
5088
5089 // - Common fields
5090 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5091 CXTok.int_data[2] = Tok.getLength();
5092 CXTok.int_data[3] = 0;
5093
5094 // - Kind-specific fields
5095 if (Tok.isLiteral()) {
5096 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005097 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005098 } else if (Tok.is(tok::raw_identifier)) {
5099 // Lookup the identifier to determine whether we have a keyword.
5100 IdentifierInfo *II
5101 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5102
5103 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5104 CXTok.int_data[0] = CXToken_Keyword;
5105 }
5106 else {
5107 CXTok.int_data[0] = Tok.is(tok::identifier)
5108 ? CXToken_Identifier
5109 : CXToken_Keyword;
5110 }
5111 CXTok.ptr_data = II;
5112 } else if (Tok.is(tok::comment)) {
5113 CXTok.int_data[0] = CXToken_Comment;
5114 CXTok.ptr_data = 0;
5115 } else {
5116 CXTok.int_data[0] = CXToken_Punctuation;
5117 CXTok.ptr_data = 0;
5118 }
5119 CXTokens.push_back(CXTok);
5120 previousWasAt = Tok.is(tok::at);
5121 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5122}
5123
5124void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5125 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005126 LOG_FUNC_SECTION {
5127 *Log << TU << ' ' << Range;
5128 }
5129
Guy Benyei11169dd2012-12-18 14:30:41 +00005130 if (Tokens)
5131 *Tokens = 0;
5132 if (NumTokens)
5133 *NumTokens = 0;
5134
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005135 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005136 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005137 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005138 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005139
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005140 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005141 if (!CXXUnit || !Tokens || !NumTokens)
5142 return;
5143
5144 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5145
5146 SourceRange R = cxloc::translateCXSourceRange(Range);
5147 if (R.isInvalid())
5148 return;
5149
5150 SmallVector<CXToken, 32> CXTokens;
5151 getTokens(CXXUnit, R, CXTokens);
5152
5153 if (CXTokens.empty())
5154 return;
5155
5156 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5157 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5158 *NumTokens = CXTokens.size();
5159}
5160
5161void clang_disposeTokens(CXTranslationUnit TU,
5162 CXToken *Tokens, unsigned NumTokens) {
5163 free(Tokens);
5164}
5165
5166} // end: extern "C"
5167
5168//===----------------------------------------------------------------------===//
5169// Token annotation APIs.
5170//===----------------------------------------------------------------------===//
5171
Guy Benyei11169dd2012-12-18 14:30:41 +00005172static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5173 CXCursor parent,
5174 CXClientData client_data);
5175static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5176 CXClientData client_data);
5177
5178namespace {
5179class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005180 CXToken *Tokens;
5181 CXCursor *Cursors;
5182 unsigned NumTokens;
5183 unsigned TokIdx;
5184 unsigned PreprocessingTokIdx;
5185 CursorVisitor AnnotateVis;
5186 SourceManager &SrcMgr;
5187 bool HasContextSensitiveKeywords;
5188
5189 struct PostChildrenInfo {
5190 CXCursor Cursor;
5191 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005192 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005193 unsigned BeforeChildrenTokenIdx;
5194 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005195 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005196
5197 CXToken &getTok(unsigned Idx) {
5198 assert(Idx < NumTokens);
5199 return Tokens[Idx];
5200 }
5201 const CXToken &getTok(unsigned Idx) const {
5202 assert(Idx < NumTokens);
5203 return Tokens[Idx];
5204 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005205 bool MoreTokens() const { return TokIdx < NumTokens; }
5206 unsigned NextToken() const { return TokIdx; }
5207 void AdvanceToken() { ++TokIdx; }
5208 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005209 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005210 }
5211 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005212 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005213 }
5214 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005215 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005216 }
5217
5218 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005219 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005220 SourceRange);
5221
5222public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005223 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005224 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005225 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005226 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005227 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005228 AnnotateTokensVisitor, this,
5229 /*VisitPreprocessorLast=*/true,
5230 /*VisitIncludedEntities=*/false,
5231 RegionOfInterest,
5232 /*VisitDeclsOnly=*/false,
5233 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005234 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005235 HasContextSensitiveKeywords(false) { }
5236
5237 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5238 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5239 bool postVisitChildren(CXCursor cursor);
5240 void AnnotateTokens();
5241
5242 /// \brief Determine whether the annotator saw any cursors that have
5243 /// context-sensitive keywords.
5244 bool hasContextSensitiveKeywords() const {
5245 return HasContextSensitiveKeywords;
5246 }
5247
5248 ~AnnotateTokensWorker() {
5249 assert(PostChildrenInfos.empty());
5250 }
5251};
5252}
5253
5254void AnnotateTokensWorker::AnnotateTokens() {
5255 // Walk the AST within the region of interest, annotating tokens
5256 // along the way.
5257 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005258}
Guy Benyei11169dd2012-12-18 14:30:41 +00005259
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005260static inline void updateCursorAnnotation(CXCursor &Cursor,
5261 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005262 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005263 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005264 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005265}
5266
5267/// \brief It annotates and advances tokens with a cursor until the comparison
5268//// between the cursor location and the source range is the same as
5269/// \arg compResult.
5270///
5271/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5272/// Pass RangeOverlap to annotate tokens inside a range.
5273void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5274 RangeComparisonResult compResult,
5275 SourceRange range) {
5276 while (MoreTokens()) {
5277 const unsigned I = NextToken();
5278 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005279 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5280 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005281
5282 SourceLocation TokLoc = GetTokenLoc(I);
5283 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005284 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005285 AdvanceToken();
5286 continue;
5287 }
5288 break;
5289 }
5290}
5291
5292/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005293/// \returns true if it advanced beyond all macro tokens, false otherwise.
5294bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005295 CXCursor updateC,
5296 RangeComparisonResult compResult,
5297 SourceRange range) {
5298 assert(MoreTokens());
5299 assert(isFunctionMacroToken(NextToken()) &&
5300 "Should be called only for macro arg tokens");
5301
5302 // This works differently than annotateAndAdvanceTokens; because expanded
5303 // macro arguments can have arbitrary translation-unit source order, we do not
5304 // advance the token index one by one until a token fails the range test.
5305 // We only advance once past all of the macro arg tokens if all of them
5306 // pass the range test. If one of them fails we keep the token index pointing
5307 // at the start of the macro arg tokens so that the failing token will be
5308 // annotated by a subsequent annotation try.
5309
5310 bool atLeastOneCompFail = false;
5311
5312 unsigned I = NextToken();
5313 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5314 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5315 if (TokLoc.isFileID())
5316 continue; // not macro arg token, it's parens or comma.
5317 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5318 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5319 Cursors[I] = updateC;
5320 } else
5321 atLeastOneCompFail = true;
5322 }
5323
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005324 if (atLeastOneCompFail)
5325 return false;
5326
5327 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5328 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005329}
5330
5331enum CXChildVisitResult
5332AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005333 SourceRange cursorRange = getRawCursorExtent(cursor);
5334 if (cursorRange.isInvalid())
5335 return CXChildVisit_Recurse;
5336
5337 if (!HasContextSensitiveKeywords) {
5338 // Objective-C properties can have context-sensitive keywords.
5339 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005340 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005341 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5342 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5343 }
5344 // Objective-C methods can have context-sensitive keywords.
5345 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5346 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005347 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005348 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5349 if (Method->getObjCDeclQualifier())
5350 HasContextSensitiveKeywords = true;
5351 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005352 for (const auto *P : Method->params()) {
5353 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005354 HasContextSensitiveKeywords = true;
5355 break;
5356 }
5357 }
5358 }
5359 }
5360 }
5361 // C++ methods can have context-sensitive keywords.
5362 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005363 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005364 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5365 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5366 HasContextSensitiveKeywords = true;
5367 }
5368 }
5369 // C++ classes can have context-sensitive keywords.
5370 else if (cursor.kind == CXCursor_StructDecl ||
5371 cursor.kind == CXCursor_ClassDecl ||
5372 cursor.kind == CXCursor_ClassTemplate ||
5373 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005374 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005375 if (D->hasAttr<FinalAttr>())
5376 HasContextSensitiveKeywords = true;
5377 }
5378 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005379
5380 // Don't override a property annotation with its getter/setter method.
5381 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5382 parent.kind == CXCursor_ObjCPropertyDecl)
5383 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005384
5385 if (clang_isPreprocessing(cursor.kind)) {
5386 // Items in the preprocessing record are kept separate from items in
5387 // declarations, so we keep a separate token index.
5388 unsigned SavedTokIdx = TokIdx;
5389 TokIdx = PreprocessingTokIdx;
5390
5391 // Skip tokens up until we catch up to the beginning of the preprocessing
5392 // entry.
5393 while (MoreTokens()) {
5394 const unsigned I = NextToken();
5395 SourceLocation TokLoc = GetTokenLoc(I);
5396 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5397 case RangeBefore:
5398 AdvanceToken();
5399 continue;
5400 case RangeAfter:
5401 case RangeOverlap:
5402 break;
5403 }
5404 break;
5405 }
5406
5407 // Look at all of the tokens within this range.
5408 while (MoreTokens()) {
5409 const unsigned I = NextToken();
5410 SourceLocation TokLoc = GetTokenLoc(I);
5411 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5412 case RangeBefore:
5413 llvm_unreachable("Infeasible");
5414 case RangeAfter:
5415 break;
5416 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005417 // For macro expansions, just note where the beginning of the macro
5418 // expansion occurs.
5419 if (cursor.kind == CXCursor_MacroExpansion) {
5420 if (TokLoc == cursorRange.getBegin())
5421 Cursors[I] = cursor;
5422 AdvanceToken();
5423 break;
5424 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005425 // We may have already annotated macro names inside macro definitions.
5426 if (Cursors[I].kind != CXCursor_MacroExpansion)
5427 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005428 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005429 continue;
5430 }
5431 break;
5432 }
5433
5434 // Save the preprocessing token index; restore the non-preprocessing
5435 // token index.
5436 PreprocessingTokIdx = TokIdx;
5437 TokIdx = SavedTokIdx;
5438 return CXChildVisit_Recurse;
5439 }
5440
5441 if (cursorRange.isInvalid())
5442 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005443
5444 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005445 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005446 const enum CXCursorKind K = clang_getCursorKind(parent);
5447 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005448 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5449 // Attributes are annotated out-of-order, skip tokens until we reach it.
5450 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005451 ? clang_getNullCursor() : parent;
5452
5453 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5454
5455 // Avoid having the cursor of an expression "overwrite" the annotation of the
5456 // variable declaration that it belongs to.
5457 // This can happen for C++ constructor expressions whose range generally
5458 // include the variable declaration, e.g.:
5459 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005460 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005461 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005462 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005463 const unsigned I = NextToken();
5464 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5465 E->getLocStart() == D->getLocation() &&
5466 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005467 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005468 AdvanceToken();
5469 }
5470 }
5471 }
5472
5473 // Before recursing into the children keep some state that we are going
5474 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5475 // extra work after the child nodes are visited.
5476 // Note that we don't call VisitChildren here to avoid traversing statements
5477 // code-recursively which can blow the stack.
5478
5479 PostChildrenInfo Info;
5480 Info.Cursor = cursor;
5481 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005482 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005483 Info.BeforeChildrenTokenIdx = NextToken();
5484 PostChildrenInfos.push_back(Info);
5485
5486 return CXChildVisit_Recurse;
5487}
5488
5489bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5490 if (PostChildrenInfos.empty())
5491 return false;
5492 const PostChildrenInfo &Info = PostChildrenInfos.back();
5493 if (!clang_equalCursors(Info.Cursor, cursor))
5494 return false;
5495
5496 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5497 const unsigned AfterChildren = NextToken();
5498 SourceRange cursorRange = Info.CursorRange;
5499
5500 // Scan the tokens that are at the end of the cursor, but are not captured
5501 // but the child cursors.
5502 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5503
5504 // Scan the tokens that are at the beginning of the cursor, but are not
5505 // capture by the child cursors.
5506 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5507 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5508 break;
5509
5510 Cursors[I] = cursor;
5511 }
5512
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005513 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5514 // encountered the attribute cursor.
5515 if (clang_isAttribute(cursor.kind))
5516 TokIdx = Info.BeforeReachingCursorIdx;
5517
Guy Benyei11169dd2012-12-18 14:30:41 +00005518 PostChildrenInfos.pop_back();
5519 return false;
5520}
5521
5522static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5523 CXCursor parent,
5524 CXClientData client_data) {
5525 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5526}
5527
5528static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5529 CXClientData client_data) {
5530 return static_cast<AnnotateTokensWorker*>(client_data)->
5531 postVisitChildren(cursor);
5532}
5533
5534namespace {
5535
5536/// \brief Uses the macro expansions in the preprocessing record to find
5537/// and mark tokens that are macro arguments. This info is used by the
5538/// AnnotateTokensWorker.
5539class MarkMacroArgTokensVisitor {
5540 SourceManager &SM;
5541 CXToken *Tokens;
5542 unsigned NumTokens;
5543 unsigned CurIdx;
5544
5545public:
5546 MarkMacroArgTokensVisitor(SourceManager &SM,
5547 CXToken *tokens, unsigned numTokens)
5548 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5549
5550 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5551 if (cursor.kind != CXCursor_MacroExpansion)
5552 return CXChildVisit_Continue;
5553
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005554 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005555 if (macroRange.getBegin() == macroRange.getEnd())
5556 return CXChildVisit_Continue; // it's not a function macro.
5557
5558 for (; CurIdx < NumTokens; ++CurIdx) {
5559 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5560 macroRange.getBegin()))
5561 break;
5562 }
5563
5564 if (CurIdx == NumTokens)
5565 return CXChildVisit_Break;
5566
5567 for (; CurIdx < NumTokens; ++CurIdx) {
5568 SourceLocation tokLoc = getTokenLoc(CurIdx);
5569 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5570 break;
5571
5572 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5573 }
5574
5575 if (CurIdx == NumTokens)
5576 return CXChildVisit_Break;
5577
5578 return CXChildVisit_Continue;
5579 }
5580
5581private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005582 CXToken &getTok(unsigned Idx) {
5583 assert(Idx < NumTokens);
5584 return Tokens[Idx];
5585 }
5586 const CXToken &getTok(unsigned Idx) const {
5587 assert(Idx < NumTokens);
5588 return Tokens[Idx];
5589 }
5590
Guy Benyei11169dd2012-12-18 14:30:41 +00005591 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005592 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005593 }
5594
5595 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5596 // The third field is reserved and currently not used. Use it here
5597 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005598 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005599 }
5600};
5601
5602} // end anonymous namespace
5603
5604static CXChildVisitResult
5605MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5606 CXClientData client_data) {
5607 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5608 parent);
5609}
5610
5611namespace {
5612 struct clang_annotateTokens_Data {
5613 CXTranslationUnit TU;
5614 ASTUnit *CXXUnit;
5615 CXToken *Tokens;
5616 unsigned NumTokens;
5617 CXCursor *Cursors;
5618 };
5619}
5620
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005621/// \brief Used by \c annotatePreprocessorTokens.
5622/// \returns true if lexing was finished, false otherwise.
5623static bool lexNext(Lexer &Lex, Token &Tok,
5624 unsigned &NextIdx, unsigned NumTokens) {
5625 if (NextIdx >= NumTokens)
5626 return true;
5627
5628 ++NextIdx;
5629 Lex.LexFromRawLexer(Tok);
5630 if (Tok.is(tok::eof))
5631 return true;
5632
5633 return false;
5634}
5635
Guy Benyei11169dd2012-12-18 14:30:41 +00005636static void annotatePreprocessorTokens(CXTranslationUnit TU,
5637 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005638 CXCursor *Cursors,
5639 CXToken *Tokens,
5640 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005641 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005642
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005643 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005644 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5645 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005646 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005647 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005648 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005649
5650 if (BeginLocInfo.first != EndLocInfo.first)
5651 return;
5652
5653 StringRef Buffer;
5654 bool Invalid = false;
5655 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5656 if (Buffer.empty() || Invalid)
5657 return;
5658
5659 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5660 CXXUnit->getASTContext().getLangOpts(),
5661 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5662 Buffer.end());
5663 Lex.SetCommentRetentionState(true);
5664
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005665 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005666 // Lex tokens in raw mode until we hit the end of the range, to avoid
5667 // entering #includes or expanding macros.
5668 while (true) {
5669 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005670 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5671 break;
5672 unsigned TokIdx = NextIdx-1;
5673 assert(Tok.getLocation() ==
5674 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005675
5676 reprocess:
5677 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005678 // We have found a preprocessing directive. Annotate the tokens
5679 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005680 //
5681 // FIXME: Some simple tests here could identify macro definitions and
5682 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005683
5684 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005685 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5686 break;
5687
5688 MacroInfo *MI = 0;
5689 if (Tok.is(tok::raw_identifier) &&
5690 StringRef(Tok.getRawIdentifierData(), Tok.getLength()) == "define") {
5691 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5692 break;
5693
5694 if (Tok.is(tok::raw_identifier)) {
5695 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
5696 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
5697 SourceLocation MappedTokLoc =
5698 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5699 MI = getMacroInfo(II, MappedTokLoc, TU);
5700 }
5701 }
5702
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005703 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005704 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005705 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5706 finished = true;
5707 break;
5708 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005709 // If we are in a macro definition, check if the token was ever a
5710 // macro name and annotate it if that's the case.
5711 if (MI) {
5712 SourceLocation SaveLoc = Tok.getLocation();
5713 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5714 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5715 Tok.setLocation(SaveLoc);
5716 if (MacroDef)
5717 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5718 Tok.getLocation(), TU);
5719 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005720 } while (!Tok.isAtStartOfLine());
5721
5722 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5723 assert(TokIdx <= LastIdx);
5724 SourceLocation EndLoc =
5725 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5726 CXCursor Cursor =
5727 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5728
5729 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005730 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005731
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005732 if (finished)
5733 break;
5734 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005735 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005736 }
5737}
5738
5739// This gets run a separate thread to avoid stack blowout.
5740static void clang_annotateTokensImpl(void *UserData) {
5741 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5742 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5743 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5744 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5745 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5746
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005747 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005748 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5749 setThreadBackgroundPriority();
5750
5751 // Determine the region of interest, which contains all of the tokens.
5752 SourceRange RegionOfInterest;
5753 RegionOfInterest.setBegin(
5754 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5755 RegionOfInterest.setEnd(
5756 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5757 Tokens[NumTokens-1])));
5758
Guy Benyei11169dd2012-12-18 14:30:41 +00005759 // Relex the tokens within the source range to look for preprocessing
5760 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005761 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005762
5763 // If begin location points inside a macro argument, set it to the expansion
5764 // location so we can have the full context when annotating semantically.
5765 {
5766 SourceManager &SM = CXXUnit->getSourceManager();
5767 SourceLocation Loc =
5768 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5769 if (Loc.isMacroID())
5770 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5771 }
5772
Guy Benyei11169dd2012-12-18 14:30:41 +00005773 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5774 // Search and mark tokens that are macro argument expansions.
5775 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5776 Tokens, NumTokens);
5777 CursorVisitor MacroArgMarker(TU,
5778 MarkMacroArgTokensVisitorDelegate, &Visitor,
5779 /*VisitPreprocessorLast=*/true,
5780 /*VisitIncludedEntities=*/false,
5781 RegionOfInterest);
5782 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5783 }
5784
5785 // Annotate all of the source locations in the region of interest that map to
5786 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005787 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005788
5789 // FIXME: We use a ridiculous stack size here because the data-recursion
5790 // algorithm uses a large stack frame than the non-data recursive version,
5791 // and AnnotationTokensWorker currently transforms the data-recursion
5792 // algorithm back into a traditional recursion by explicitly calling
5793 // VisitChildren(). We will need to remove this explicit recursive call.
5794 W.AnnotateTokens();
5795
5796 // If we ran into any entities that involve context-sensitive keywords,
5797 // take another pass through the tokens to mark them as such.
5798 if (W.hasContextSensitiveKeywords()) {
5799 for (unsigned I = 0; I != NumTokens; ++I) {
5800 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5801 continue;
5802
5803 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5804 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005805 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005806 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5807 if (Property->getPropertyAttributesAsWritten() != 0 &&
5808 llvm::StringSwitch<bool>(II->getName())
5809 .Case("readonly", true)
5810 .Case("assign", true)
5811 .Case("unsafe_unretained", true)
5812 .Case("readwrite", true)
5813 .Case("retain", true)
5814 .Case("copy", true)
5815 .Case("nonatomic", true)
5816 .Case("atomic", true)
5817 .Case("getter", true)
5818 .Case("setter", true)
5819 .Case("strong", true)
5820 .Case("weak", true)
5821 .Default(false))
5822 Tokens[I].int_data[0] = CXToken_Keyword;
5823 }
5824 continue;
5825 }
5826
5827 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5828 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5829 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5830 if (llvm::StringSwitch<bool>(II->getName())
5831 .Case("in", true)
5832 .Case("out", true)
5833 .Case("inout", true)
5834 .Case("oneway", true)
5835 .Case("bycopy", true)
5836 .Case("byref", true)
5837 .Default(false))
5838 Tokens[I].int_data[0] = CXToken_Keyword;
5839 continue;
5840 }
5841
5842 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5843 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5844 Tokens[I].int_data[0] = CXToken_Keyword;
5845 continue;
5846 }
5847 }
5848 }
5849}
5850
5851extern "C" {
5852
5853void clang_annotateTokens(CXTranslationUnit TU,
5854 CXToken *Tokens, unsigned NumTokens,
5855 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005856 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005857 LOG_BAD_TU(TU);
5858 return;
5859 }
5860 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005861 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005862 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005863 }
5864
5865 LOG_FUNC_SECTION {
5866 *Log << TU << ' ';
5867 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5868 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5869 *Log << clang_getRange(bloc, eloc);
5870 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005871
5872 // Any token we don't specifically annotate will have a NULL cursor.
5873 CXCursor C = clang_getNullCursor();
5874 for (unsigned I = 0; I != NumTokens; ++I)
5875 Cursors[I] = C;
5876
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005877 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005878 if (!CXXUnit)
5879 return;
5880
5881 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5882
5883 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5884 llvm::CrashRecoveryContext CRC;
5885 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5886 GetSafetyThreadStackSize() * 2)) {
5887 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5888 }
5889}
5890
5891} // end: extern "C"
5892
5893//===----------------------------------------------------------------------===//
5894// Operations for querying linkage of a cursor.
5895//===----------------------------------------------------------------------===//
5896
5897extern "C" {
5898CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5899 if (!clang_isDeclaration(cursor.kind))
5900 return CXLinkage_Invalid;
5901
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005902 const Decl *D = cxcursor::getCursorDecl(cursor);
5903 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005904 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005905 case NoLinkage:
5906 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005907 case InternalLinkage: return CXLinkage_Internal;
5908 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5909 case ExternalLinkage: return CXLinkage_External;
5910 };
5911
5912 return CXLinkage_Invalid;
5913}
5914} // end: extern "C"
5915
5916//===----------------------------------------------------------------------===//
5917// Operations for querying language of a cursor.
5918//===----------------------------------------------------------------------===//
5919
5920static CXLanguageKind getDeclLanguage(const Decl *D) {
5921 if (!D)
5922 return CXLanguage_C;
5923
5924 switch (D->getKind()) {
5925 default:
5926 break;
5927 case Decl::ImplicitParam:
5928 case Decl::ObjCAtDefsField:
5929 case Decl::ObjCCategory:
5930 case Decl::ObjCCategoryImpl:
5931 case Decl::ObjCCompatibleAlias:
5932 case Decl::ObjCImplementation:
5933 case Decl::ObjCInterface:
5934 case Decl::ObjCIvar:
5935 case Decl::ObjCMethod:
5936 case Decl::ObjCProperty:
5937 case Decl::ObjCPropertyImpl:
5938 case Decl::ObjCProtocol:
5939 return CXLanguage_ObjC;
5940 case Decl::CXXConstructor:
5941 case Decl::CXXConversion:
5942 case Decl::CXXDestructor:
5943 case Decl::CXXMethod:
5944 case Decl::CXXRecord:
5945 case Decl::ClassTemplate:
5946 case Decl::ClassTemplatePartialSpecialization:
5947 case Decl::ClassTemplateSpecialization:
5948 case Decl::Friend:
5949 case Decl::FriendTemplate:
5950 case Decl::FunctionTemplate:
5951 case Decl::LinkageSpec:
5952 case Decl::Namespace:
5953 case Decl::NamespaceAlias:
5954 case Decl::NonTypeTemplateParm:
5955 case Decl::StaticAssert:
5956 case Decl::TemplateTemplateParm:
5957 case Decl::TemplateTypeParm:
5958 case Decl::UnresolvedUsingTypename:
5959 case Decl::UnresolvedUsingValue:
5960 case Decl::Using:
5961 case Decl::UsingDirective:
5962 case Decl::UsingShadow:
5963 return CXLanguage_CPlusPlus;
5964 }
5965
5966 return CXLanguage_C;
5967}
5968
5969extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005970
5971static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5972 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5973 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005974
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005975 switch (D->getAvailability()) {
5976 case AR_Available:
5977 case AR_NotYetIntroduced:
5978 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00005979 return getCursorAvailabilityForDecl(
5980 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005981 return CXAvailability_Available;
5982
5983 case AR_Deprecated:
5984 return CXAvailability_Deprecated;
5985
5986 case AR_Unavailable:
5987 return CXAvailability_NotAvailable;
5988 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00005989
5990 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005991}
5992
Guy Benyei11169dd2012-12-18 14:30:41 +00005993enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
5994 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005995 if (const Decl *D = cxcursor::getCursorDecl(cursor))
5996 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00005997
5998 return CXAvailability_Available;
5999}
6000
6001static CXVersion convertVersion(VersionTuple In) {
6002 CXVersion Out = { -1, -1, -1 };
6003 if (In.empty())
6004 return Out;
6005
6006 Out.Major = In.getMajor();
6007
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006008 Optional<unsigned> Minor = In.getMinor();
6009 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006010 Out.Minor = *Minor;
6011 else
6012 return Out;
6013
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006014 Optional<unsigned> Subminor = In.getSubminor();
6015 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006016 Out.Subminor = *Subminor;
6017
6018 return Out;
6019}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006020
6021static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6022 int *always_deprecated,
6023 CXString *deprecated_message,
6024 int *always_unavailable,
6025 CXString *unavailable_message,
6026 CXPlatformAvailability *availability,
6027 int availability_size) {
6028 bool HadAvailAttr = false;
6029 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006030 for (auto A : D->attrs()) {
6031 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006032 HadAvailAttr = true;
6033 if (always_deprecated)
6034 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006035 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006036 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006037 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006038 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006039 continue;
6040 }
6041
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006042 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006043 HadAvailAttr = true;
6044 if (always_unavailable)
6045 *always_unavailable = 1;
6046 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006047 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006048 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6049 }
6050 continue;
6051 }
6052
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006053 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006054 HadAvailAttr = true;
6055 if (N < availability_size) {
6056 availability[N].Platform
6057 = cxstring::createDup(Avail->getPlatform()->getName());
6058 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6059 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6060 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6061 availability[N].Unavailable = Avail->getUnavailable();
6062 availability[N].Message = cxstring::createDup(Avail->getMessage());
6063 }
6064 ++N;
6065 }
6066 }
6067
6068 if (!HadAvailAttr)
6069 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6070 return getCursorPlatformAvailabilityForDecl(
6071 cast<Decl>(EnumConst->getDeclContext()),
6072 always_deprecated,
6073 deprecated_message,
6074 always_unavailable,
6075 unavailable_message,
6076 availability,
6077 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006078
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006079 return N;
6080}
6081
Guy Benyei11169dd2012-12-18 14:30:41 +00006082int clang_getCursorPlatformAvailability(CXCursor cursor,
6083 int *always_deprecated,
6084 CXString *deprecated_message,
6085 int *always_unavailable,
6086 CXString *unavailable_message,
6087 CXPlatformAvailability *availability,
6088 int availability_size) {
6089 if (always_deprecated)
6090 *always_deprecated = 0;
6091 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006092 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006093 if (always_unavailable)
6094 *always_unavailable = 0;
6095 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006096 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006097
Guy Benyei11169dd2012-12-18 14:30:41 +00006098 if (!clang_isDeclaration(cursor.kind))
6099 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006100
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006101 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006102 if (!D)
6103 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006104
6105 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6106 deprecated_message,
6107 always_unavailable,
6108 unavailable_message,
6109 availability,
6110 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006111}
6112
6113void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6114 clang_disposeString(availability->Platform);
6115 clang_disposeString(availability->Message);
6116}
6117
6118CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6119 if (clang_isDeclaration(cursor.kind))
6120 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6121
6122 return CXLanguage_Invalid;
6123}
6124
6125 /// \brief If the given cursor is the "templated" declaration
6126 /// descibing a class or function template, return the class or
6127 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006128static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006129 if (!D)
6130 return 0;
6131
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006132 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006133 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6134 return FunTmpl;
6135
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006136 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006137 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6138 return ClassTmpl;
6139
6140 return D;
6141}
6142
6143CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6144 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006145 if (const Decl *D = getCursorDecl(cursor)) {
6146 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006147 if (!DC)
6148 return clang_getNullCursor();
6149
6150 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6151 getCursorTU(cursor));
6152 }
6153 }
6154
6155 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006156 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006157 return MakeCXCursor(D, getCursorTU(cursor));
6158 }
6159
6160 return clang_getNullCursor();
6161}
6162
6163CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6164 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006165 if (const Decl *D = getCursorDecl(cursor)) {
6166 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006167 if (!DC)
6168 return clang_getNullCursor();
6169
6170 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6171 getCursorTU(cursor));
6172 }
6173 }
6174
6175 // FIXME: Note that we can't easily compute the lexical context of a
6176 // statement or expression, so we return nothing.
6177 return clang_getNullCursor();
6178}
6179
6180CXFile clang_getIncludedFile(CXCursor cursor) {
6181 if (cursor.kind != CXCursor_InclusionDirective)
6182 return 0;
6183
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006184 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006185 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006186}
6187
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006188unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6189 if (C.kind != CXCursor_ObjCPropertyDecl)
6190 return CXObjCPropertyAttr_noattr;
6191
6192 unsigned Result = CXObjCPropertyAttr_noattr;
6193 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6194 ObjCPropertyDecl::PropertyAttributeKind Attr =
6195 PD->getPropertyAttributesAsWritten();
6196
6197#define SET_CXOBJCPROP_ATTR(A) \
6198 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6199 Result |= CXObjCPropertyAttr_##A
6200 SET_CXOBJCPROP_ATTR(readonly);
6201 SET_CXOBJCPROP_ATTR(getter);
6202 SET_CXOBJCPROP_ATTR(assign);
6203 SET_CXOBJCPROP_ATTR(readwrite);
6204 SET_CXOBJCPROP_ATTR(retain);
6205 SET_CXOBJCPROP_ATTR(copy);
6206 SET_CXOBJCPROP_ATTR(nonatomic);
6207 SET_CXOBJCPROP_ATTR(setter);
6208 SET_CXOBJCPROP_ATTR(atomic);
6209 SET_CXOBJCPROP_ATTR(weak);
6210 SET_CXOBJCPROP_ATTR(strong);
6211 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6212#undef SET_CXOBJCPROP_ATTR
6213
6214 return Result;
6215}
6216
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006217unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6218 if (!clang_isDeclaration(C.kind))
6219 return CXObjCDeclQualifier_None;
6220
6221 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6222 const Decl *D = getCursorDecl(C);
6223 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6224 QT = MD->getObjCDeclQualifier();
6225 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6226 QT = PD->getObjCDeclQualifier();
6227 if (QT == Decl::OBJC_TQ_None)
6228 return CXObjCDeclQualifier_None;
6229
6230 unsigned Result = CXObjCDeclQualifier_None;
6231 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6232 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6233 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6234 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6235 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6236 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6237
6238 return Result;
6239}
6240
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006241unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6242 if (!clang_isDeclaration(C.kind))
6243 return 0;
6244
6245 const Decl *D = getCursorDecl(C);
6246 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6247 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6248 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6249 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6250
6251 return 0;
6252}
6253
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006254unsigned clang_Cursor_isVariadic(CXCursor C) {
6255 if (!clang_isDeclaration(C.kind))
6256 return 0;
6257
6258 const Decl *D = getCursorDecl(C);
6259 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6260 return FD->isVariadic();
6261 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6262 return MD->isVariadic();
6263
6264 return 0;
6265}
6266
Guy Benyei11169dd2012-12-18 14:30:41 +00006267CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6268 if (!clang_isDeclaration(C.kind))
6269 return clang_getNullRange();
6270
6271 const Decl *D = getCursorDecl(C);
6272 ASTContext &Context = getCursorContext(C);
6273 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6274 if (!RC)
6275 return clang_getNullRange();
6276
6277 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6278}
6279
6280CXString clang_Cursor_getRawCommentText(CXCursor C) {
6281 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006282 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006283
6284 const Decl *D = getCursorDecl(C);
6285 ASTContext &Context = getCursorContext(C);
6286 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6287 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6288 StringRef();
6289
6290 // Don't duplicate the string because RawText points directly into source
6291 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006292 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006293}
6294
6295CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6296 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006297 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006298
6299 const Decl *D = getCursorDecl(C);
6300 const ASTContext &Context = getCursorContext(C);
6301 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6302
6303 if (RC) {
6304 StringRef BriefText = RC->getBriefText(Context);
6305
6306 // Don't duplicate the string because RawComment ensures that this memory
6307 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006308 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006309 }
6310
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006311 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006312}
6313
Guy Benyei11169dd2012-12-18 14:30:41 +00006314CXModule clang_Cursor_getModule(CXCursor C) {
6315 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006316 if (const ImportDecl *ImportD =
6317 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006318 return ImportD->getImportedModule();
6319 }
6320
6321 return 0;
6322}
6323
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006324CXFile clang_Module_getASTFile(CXModule CXMod) {
6325 if (!CXMod)
6326 return 0;
6327 Module *Mod = static_cast<Module*>(CXMod);
6328 return const_cast<FileEntry *>(Mod->getASTFile());
6329}
6330
Guy Benyei11169dd2012-12-18 14:30:41 +00006331CXModule clang_Module_getParent(CXModule CXMod) {
6332 if (!CXMod)
6333 return 0;
6334 Module *Mod = static_cast<Module*>(CXMod);
6335 return Mod->Parent;
6336}
6337
6338CXString clang_Module_getName(CXModule CXMod) {
6339 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006340 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006341 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006342 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006343}
6344
6345CXString clang_Module_getFullName(CXModule CXMod) {
6346 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006347 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006348 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006349 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006350}
6351
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006352unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6353 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006354 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006355 LOG_BAD_TU(TU);
6356 return 0;
6357 }
6358 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006359 return 0;
6360 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006361 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6362 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6363 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006364}
6365
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006366CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6367 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006368 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006369 LOG_BAD_TU(TU);
6370 return 0;
6371 }
6372 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006373 return 0;
6374 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006375 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006376
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006377 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6378 if (Index < TopHeaders.size())
6379 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006380
6381 return 0;
6382}
6383
6384} // end: extern "C"
6385
6386//===----------------------------------------------------------------------===//
6387// C++ AST instrospection.
6388//===----------------------------------------------------------------------===//
6389
6390extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006391unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6392 if (!clang_isDeclaration(C.kind))
6393 return 0;
6394
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006395 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006396 const CXXMethodDecl *Method =
6397 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006398 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6399}
6400
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006401unsigned clang_CXXMethod_isConst(CXCursor C) {
6402 if (!clang_isDeclaration(C.kind))
6403 return 0;
6404
6405 const Decl *D = cxcursor::getCursorDecl(C);
6406 const CXXMethodDecl *Method =
6407 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
6408 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6409}
6410
Guy Benyei11169dd2012-12-18 14:30:41 +00006411unsigned clang_CXXMethod_isStatic(CXCursor C) {
6412 if (!clang_isDeclaration(C.kind))
6413 return 0;
6414
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006415 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006416 const CXXMethodDecl *Method =
6417 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006418 return (Method && Method->isStatic()) ? 1 : 0;
6419}
6420
6421unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6422 if (!clang_isDeclaration(C.kind))
6423 return 0;
6424
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006425 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006426 const CXXMethodDecl *Method =
6427 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006428 return (Method && Method->isVirtual()) ? 1 : 0;
6429}
6430} // end: extern "C"
6431
6432//===----------------------------------------------------------------------===//
6433// Attribute introspection.
6434//===----------------------------------------------------------------------===//
6435
6436extern "C" {
6437CXType clang_getIBOutletCollectionType(CXCursor C) {
6438 if (C.kind != CXCursor_IBOutletCollectionAttr)
6439 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6440
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006441 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006442 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6443
6444 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6445}
6446} // end: extern "C"
6447
6448//===----------------------------------------------------------------------===//
6449// Inspecting memory usage.
6450//===----------------------------------------------------------------------===//
6451
6452typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6453
6454static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6455 enum CXTUResourceUsageKind k,
6456 unsigned long amount) {
6457 CXTUResourceUsageEntry entry = { k, amount };
6458 entries.push_back(entry);
6459}
6460
6461extern "C" {
6462
6463const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6464 const char *str = "";
6465 switch (kind) {
6466 case CXTUResourceUsage_AST:
6467 str = "ASTContext: expressions, declarations, and types";
6468 break;
6469 case CXTUResourceUsage_Identifiers:
6470 str = "ASTContext: identifiers";
6471 break;
6472 case CXTUResourceUsage_Selectors:
6473 str = "ASTContext: selectors";
6474 break;
6475 case CXTUResourceUsage_GlobalCompletionResults:
6476 str = "Code completion: cached global results";
6477 break;
6478 case CXTUResourceUsage_SourceManagerContentCache:
6479 str = "SourceManager: content cache allocator";
6480 break;
6481 case CXTUResourceUsage_AST_SideTables:
6482 str = "ASTContext: side tables";
6483 break;
6484 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6485 str = "SourceManager: malloc'ed memory buffers";
6486 break;
6487 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6488 str = "SourceManager: mmap'ed memory buffers";
6489 break;
6490 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6491 str = "ExternalASTSource: malloc'ed memory buffers";
6492 break;
6493 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6494 str = "ExternalASTSource: mmap'ed memory buffers";
6495 break;
6496 case CXTUResourceUsage_Preprocessor:
6497 str = "Preprocessor: malloc'ed memory";
6498 break;
6499 case CXTUResourceUsage_PreprocessingRecord:
6500 str = "Preprocessor: PreprocessingRecord";
6501 break;
6502 case CXTUResourceUsage_SourceManager_DataStructures:
6503 str = "SourceManager: data structures and tables";
6504 break;
6505 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6506 str = "Preprocessor: header search tables";
6507 break;
6508 }
6509 return str;
6510}
6511
6512CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006513 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006514 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006515 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6516 return usage;
6517 }
6518
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006519 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006520 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006521 ASTContext &astContext = astUnit->getASTContext();
6522
6523 // How much memory is used by AST nodes and types?
6524 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6525 (unsigned long) astContext.getASTAllocatedMemory());
6526
6527 // How much memory is used by identifiers?
6528 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6529 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6530
6531 // How much memory is used for selectors?
6532 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6533 (unsigned long) astContext.Selectors.getTotalMemory());
6534
6535 // How much memory is used by ASTContext's side tables?
6536 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6537 (unsigned long) astContext.getSideTableAllocatedMemory());
6538
6539 // How much memory is used for caching global code completion results?
6540 unsigned long completionBytes = 0;
6541 if (GlobalCodeCompletionAllocator *completionAllocator =
6542 astUnit->getCachedCompletionAllocator().getPtr()) {
6543 completionBytes = completionAllocator->getTotalMemory();
6544 }
6545 createCXTUResourceUsageEntry(*entries,
6546 CXTUResourceUsage_GlobalCompletionResults,
6547 completionBytes);
6548
6549 // How much memory is being used by SourceManager's content cache?
6550 createCXTUResourceUsageEntry(*entries,
6551 CXTUResourceUsage_SourceManagerContentCache,
6552 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6553
6554 // How much memory is being used by the MemoryBuffer's in SourceManager?
6555 const SourceManager::MemoryBufferSizes &srcBufs =
6556 astUnit->getSourceManager().getMemoryBufferSizes();
6557
6558 createCXTUResourceUsageEntry(*entries,
6559 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6560 (unsigned long) srcBufs.malloc_bytes);
6561 createCXTUResourceUsageEntry(*entries,
6562 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6563 (unsigned long) srcBufs.mmap_bytes);
6564 createCXTUResourceUsageEntry(*entries,
6565 CXTUResourceUsage_SourceManager_DataStructures,
6566 (unsigned long) astContext.getSourceManager()
6567 .getDataStructureSizes());
6568
6569 // How much memory is being used by the ExternalASTSource?
6570 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6571 const ExternalASTSource::MemoryBufferSizes &sizes =
6572 esrc->getMemoryBufferSizes();
6573
6574 createCXTUResourceUsageEntry(*entries,
6575 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6576 (unsigned long) sizes.malloc_bytes);
6577 createCXTUResourceUsageEntry(*entries,
6578 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6579 (unsigned long) sizes.mmap_bytes);
6580 }
6581
6582 // How much memory is being used by the Preprocessor?
6583 Preprocessor &pp = astUnit->getPreprocessor();
6584 createCXTUResourceUsageEntry(*entries,
6585 CXTUResourceUsage_Preprocessor,
6586 pp.getTotalMemory());
6587
6588 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6589 createCXTUResourceUsageEntry(*entries,
6590 CXTUResourceUsage_PreprocessingRecord,
6591 pRec->getTotalMemory());
6592 }
6593
6594 createCXTUResourceUsageEntry(*entries,
6595 CXTUResourceUsage_Preprocessor_HeaderSearch,
6596 pp.getHeaderSearchInfo().getTotalMemory());
6597
6598 CXTUResourceUsage usage = { (void*) entries.get(),
6599 (unsigned) entries->size(),
6600 entries->size() ? &(*entries)[0] : 0 };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006601 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006602 return usage;
6603}
6604
6605void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6606 if (usage.data)
6607 delete (MemUsageEntries*) usage.data;
6608}
6609
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006610CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6611 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006612 skipped->count = 0;
6613 skipped->ranges = 0;
6614
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006615 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006616 LOG_BAD_TU(TU);
6617 return skipped;
6618 }
6619
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006620 if (!file)
6621 return skipped;
6622
6623 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6624 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6625 if (!ppRec)
6626 return skipped;
6627
6628 ASTContext &Ctx = astUnit->getASTContext();
6629 SourceManager &sm = Ctx.getSourceManager();
6630 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6631 FileID wantedFileID = sm.translateFile(fileEntry);
6632
6633 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6634 std::vector<SourceRange> wantedRanges;
6635 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6636 i != ei; ++i) {
6637 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6638 wantedRanges.push_back(*i);
6639 }
6640
6641 skipped->count = wantedRanges.size();
6642 skipped->ranges = new CXSourceRange[skipped->count];
6643 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6644 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6645
6646 return skipped;
6647}
6648
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006649void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6650 if (ranges) {
6651 delete[] ranges->ranges;
6652 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006653 }
6654}
6655
Guy Benyei11169dd2012-12-18 14:30:41 +00006656} // end extern "C"
6657
6658void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6659 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6660 for (unsigned I = 0; I != Usage.numEntries; ++I)
6661 fprintf(stderr, " %s: %lu\n",
6662 clang_getTUResourceUsageName(Usage.entries[I].kind),
6663 Usage.entries[I].amount);
6664
6665 clang_disposeCXTUResourceUsage(Usage);
6666}
6667
6668//===----------------------------------------------------------------------===//
6669// Misc. utility functions.
6670//===----------------------------------------------------------------------===//
6671
6672/// Default to using an 8 MB stack size on "safety" threads.
6673static unsigned SafetyStackThreadSize = 8 << 20;
6674
6675namespace clang {
6676
6677bool RunSafely(llvm::CrashRecoveryContext &CRC,
6678 void (*Fn)(void*), void *UserData,
6679 unsigned Size) {
6680 if (!Size)
6681 Size = GetSafetyThreadStackSize();
6682 if (Size)
6683 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6684 return CRC.RunSafely(Fn, UserData);
6685}
6686
6687unsigned GetSafetyThreadStackSize() {
6688 return SafetyStackThreadSize;
6689}
6690
6691void SetSafetyThreadStackSize(unsigned Value) {
6692 SafetyStackThreadSize = Value;
6693}
6694
6695}
6696
6697void clang::setThreadBackgroundPriority() {
6698 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6699 return;
6700
6701 // FIXME: Move to llvm/Support and make it cross-platform.
6702#ifdef __APPLE__
6703 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6704#endif
6705}
6706
6707void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6708 if (!Unit)
6709 return;
6710
6711 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6712 DEnd = Unit->stored_diag_end();
6713 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006714 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006715 CXString Msg = clang_formatDiagnostic(&Diag,
6716 clang_defaultDiagnosticDisplayOptions());
6717 fprintf(stderr, "%s\n", clang_getCString(Msg));
6718 clang_disposeString(Msg);
6719 }
6720#ifdef LLVM_ON_WIN32
6721 // On Windows, force a flush, since there may be multiple copies of
6722 // stderr and stdout in the file system, all with different buffers
6723 // but writing to the same device.
6724 fflush(stderr);
6725#endif
6726}
6727
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006728MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6729 SourceLocation MacroDefLoc,
6730 CXTranslationUnit TU){
6731 if (MacroDefLoc.isInvalid() || !TU)
6732 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006733 if (!II.hadMacroDefinition())
6734 return 0;
6735
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006736 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006737 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006738 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006739 if (MD) {
6740 for (MacroDirective::DefInfo
6741 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6742 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6743 return Def.getMacroInfo();
6744 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006745 }
6746
6747 return 0;
6748}
6749
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006750const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6751 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006752 if (!MacroDef || !TU)
6753 return 0;
6754 const IdentifierInfo *II = MacroDef->getName();
6755 if (!II)
6756 return 0;
6757
6758 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6759}
6760
6761MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6762 const Token &Tok,
6763 CXTranslationUnit TU) {
6764 if (!MI || !TU)
6765 return 0;
6766 if (Tok.isNot(tok::raw_identifier))
6767 return 0;
6768
6769 if (MI->getNumTokens() == 0)
6770 return 0;
6771 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6772 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006773 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006774
6775 // Check that the token is inside the definition and not its argument list.
6776 SourceManager &SM = Unit->getSourceManager();
6777 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6778 return 0;
6779 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6780 return 0;
6781
6782 Preprocessor &PP = Unit->getPreprocessor();
6783 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6784 if (!PPRec)
6785 return 0;
6786
6787 StringRef Name(Tok.getRawIdentifierData(), Tok.getLength());
6788 IdentifierInfo &II = PP.getIdentifierTable().get(Name);
6789 if (!II.hadMacroDefinition())
6790 return 0;
6791
6792 // Check that the identifier is not one of the macro arguments.
6793 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6794 return 0;
6795
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006796 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6797 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006798 return 0;
6799
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006800 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006801}
6802
6803MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6804 SourceLocation Loc,
6805 CXTranslationUnit TU) {
6806 if (Loc.isInvalid() || !MI || !TU)
6807 return 0;
6808
6809 if (MI->getNumTokens() == 0)
6810 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006811 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006812 Preprocessor &PP = Unit->getPreprocessor();
6813 if (!PP.getPreprocessingRecord())
6814 return 0;
6815 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6816 Token Tok;
6817 if (PP.getRawToken(Loc, Tok))
6818 return 0;
6819
6820 return checkForMacroInMacroDefinition(MI, Tok, TU);
6821}
6822
Guy Benyei11169dd2012-12-18 14:30:41 +00006823extern "C" {
6824
6825CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006826 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006827}
6828
6829} // end: extern "C"
6830
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006831Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6832 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006833 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006834 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006835 if (Unit->isMainFileAST())
6836 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006837 return *this;
6838 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006839 } else {
6840 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006841 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006842 return *this;
6843}
6844
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006845Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6846 *this << FE->getName();
6847 return *this;
6848}
6849
6850Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6851 CXString cursorName = clang_getCursorDisplayName(cursor);
6852 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6853 clang_disposeString(cursorName);
6854 return *this;
6855}
6856
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006857Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6858 CXFile File;
6859 unsigned Line, Column;
6860 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6861 CXString FileName = clang_getFileName(File);
6862 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6863 clang_disposeString(FileName);
6864 return *this;
6865}
6866
6867Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6868 CXSourceLocation BLoc = clang_getRangeStart(range);
6869 CXSourceLocation ELoc = clang_getRangeEnd(range);
6870
6871 CXFile BFile;
6872 unsigned BLine, BColumn;
6873 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6874
6875 CXFile EFile;
6876 unsigned ELine, EColumn;
6877 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6878
6879 CXString BFileName = clang_getFileName(BFile);
6880 if (BFile == EFile) {
6881 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6882 BLine, BColumn, ELine, EColumn);
6883 } else {
6884 CXString EFileName = clang_getFileName(EFile);
6885 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6886 BLine, BColumn)
6887 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6888 ELine, EColumn);
6889 clang_disposeString(EFileName);
6890 }
6891 clang_disposeString(BFileName);
6892 return *this;
6893}
6894
6895Logger &cxindex::Logger::operator<<(CXString Str) {
6896 *this << clang_getCString(Str);
6897 return *this;
6898}
6899
6900Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6901 LogOS << Fmt;
6902 return *this;
6903}
6904
6905cxindex::Logger::~Logger() {
6906 LogOS.flush();
6907
6908 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6909
6910 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6911
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006912 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006913 OS << "[libclang:" << Name << ':';
6914
6915 // FIXME: Portability.
6916#if HAVE_PTHREAD_H && __APPLE__
6917 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6918 OS << tid << ':';
6919#endif
6920
6921 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6922 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6923 OS << Msg.str() << '\n';
6924
6925 if (Trace) {
6926 llvm::sys::PrintStackTrace(stderr);
6927 OS << "--------------------------------------------------\n";
6928 }
6929}