blob: bf54fb93762f4d21d4f762ae4426c15082fb0ac6 [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"
Alp Toker1d257e12014-06-04 03:28:55 +000042#include "llvm/Config/llvm-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
Alp Toker1d257e12014-06-04 03:28:55 +000055#ifdef __APPLE__
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +000056#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
Alexander Musman8bd31e62014-05-27 15:12:19 +00001938void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
1939 Visitor->AddStmt(C->getNumForLoops());
1940}
1941
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001942void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) { }
Alexey Bataev756c1962013-09-24 03:17:45 +00001943
Alexey Bataevbcbadb62014-05-06 06:04:14 +00001944void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) { }
1945
Alexey Bataev756c1962013-09-24 03:17:45 +00001946template<typename T>
1947void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
Aaron Ballman2205d2a2014-03-14 15:55:35 +00001948 for (const auto *I : Node->varlists())
1949 Visitor->AddStmt(I);
Alexey Bataev756c1962013-09-24 03:17:45 +00001950}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001951
1952void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001953 VisitOMPClauseList(C);
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001954}
Alexey Bataevd5af8e42013-10-01 05:32:34 +00001955void OMPClauseEnqueue::VisitOMPFirstprivateClause(
1956 const OMPFirstprivateClause *C) {
1957 VisitOMPClauseList(C);
1958}
Alexey Bataev758e55e2013-09-06 18:03:48 +00001959void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
Alexey Bataev756c1962013-09-24 03:17:45 +00001960 VisitOMPClauseList(C);
Alexey Bataev758e55e2013-09-06 18:03:48 +00001961}
Alexander Musman8dba6642014-04-22 13:09:42 +00001962void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
1963 VisitOMPClauseList(C);
1964 Visitor->AddStmt(C->getStep());
1965}
Alexander Musmanf0d76e72014-05-29 14:36:25 +00001966void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
1967 VisitOMPClauseList(C);
1968 Visitor->AddStmt(C->getAlignment());
1969}
Alexey Bataevd48bcd82014-03-31 03:36:38 +00001970void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
1971 VisitOMPClauseList(C);
1972}
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001973}
Alexey Bataev756c1962013-09-24 03:17:45 +00001974
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00001975void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
1976 unsigned size = WL.size();
1977 OMPClauseEnqueue Visitor(this);
1978 Visitor.Visit(S);
1979 if (size == WL.size())
1980 return;
1981 // Now reverse the entries we just added. This will match the DFS
1982 // ordering performed by the worklist.
1983 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
1984 std::reverse(I, E);
1985}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001986void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001987 WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
1988}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001989void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001990 AddDecl(B->getBlockDecl());
1991}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001992void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00001993 EnqueueChildren(E);
1994 AddTypeLoc(E->getTypeSourceInfo());
1995}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00001996void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
1997 for (CompoundStmt::const_reverse_body_iterator I = S->body_rbegin(),
Guy Benyei11169dd2012-12-18 14:30:41 +00001998 E = S->body_rend(); I != E; ++I) {
1999 AddStmt(*I);
2000 }
2001}
2002void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002003VisitMSDependentExistsStmt(const MSDependentExistsStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002004 AddStmt(S->getSubStmt());
2005 AddDeclarationNameInfo(S);
2006 if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
2007 AddNestedNameSpecifierLoc(QualifierLoc);
2008}
2009
2010void EnqueueVisitor::
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002011VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002012 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2013 AddDeclarationNameInfo(E);
2014 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2015 AddNestedNameSpecifierLoc(QualifierLoc);
2016 if (!E->isImplicitAccess())
2017 AddStmt(E->getBase());
2018}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002019void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002020 // Enqueue the initializer , if any.
2021 AddStmt(E->getInitializer());
2022 // Enqueue the array size, if any.
2023 AddStmt(E->getArraySize());
2024 // Enqueue the allocated type.
2025 AddTypeLoc(E->getAllocatedTypeSourceInfo());
2026 // Enqueue the placement arguments.
2027 for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
2028 AddStmt(E->getPlacementArg(I-1));
2029}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002030void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002031 for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
2032 AddStmt(CE->getArg(I-1));
2033 AddStmt(CE->getCallee());
2034 AddStmt(CE->getArg(0));
2035}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002036void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
2037 const CXXPseudoDestructorExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002038 // Visit the name of the type being destroyed.
2039 AddTypeLoc(E->getDestroyedTypeInfo());
2040 // Visit the scope type that looks disturbingly like the nested-name-specifier
2041 // but isn't.
2042 AddTypeLoc(E->getScopeTypeInfo());
2043 // Visit the nested-name-specifier.
2044 if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
2045 AddNestedNameSpecifierLoc(QualifierLoc);
2046 // Visit base expression.
2047 AddStmt(E->getBase());
2048}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002049void EnqueueVisitor::VisitCXXScalarValueInitExpr(
2050 const CXXScalarValueInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002051 AddTypeLoc(E->getTypeSourceInfo());
2052}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002053void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
2054 const CXXTemporaryObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002055 EnqueueChildren(E);
2056 AddTypeLoc(E->getTypeSourceInfo());
2057}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002058void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002059 EnqueueChildren(E);
2060 if (E->isTypeOperand())
2061 AddTypeLoc(E->getTypeOperandSourceInfo());
2062}
2063
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002064void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
2065 const CXXUnresolvedConstructExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002066 EnqueueChildren(E);
2067 AddTypeLoc(E->getTypeSourceInfo());
2068}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002069void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002070 EnqueueChildren(E);
2071 if (E->isTypeOperand())
2072 AddTypeLoc(E->getTypeOperandSourceInfo());
2073}
2074
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002075void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002076 EnqueueChildren(S);
2077 AddDecl(S->getExceptionDecl());
2078}
2079
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002080void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002081 if (DR->hasExplicitTemplateArgs()) {
2082 AddExplicitTemplateArgs(&DR->getExplicitTemplateArgs());
2083 }
2084 WL.push_back(DeclRefExprParts(DR, Parent));
2085}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002086void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
2087 const DependentScopeDeclRefExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002088 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2089 AddDeclarationNameInfo(E);
2090 AddNestedNameSpecifierLoc(E->getQualifierLoc());
2091}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002092void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002093 unsigned size = WL.size();
2094 bool isFirst = true;
Aaron Ballman535bbcc2014-03-14 17:01:24 +00002095 for (const auto *D : S->decls()) {
2096 AddDecl(D, isFirst);
Guy Benyei11169dd2012-12-18 14:30:41 +00002097 isFirst = false;
2098 }
2099 if (size == WL.size())
2100 return;
2101 // Now reverse the entries we just added. This will match the DFS
2102 // ordering performed by the worklist.
2103 VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
2104 std::reverse(I, E);
2105}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002106void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002107 AddStmt(E->getInit());
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002108 for (DesignatedInitExpr::const_reverse_designators_iterator
Guy Benyei11169dd2012-12-18 14:30:41 +00002109 D = E->designators_rbegin(), DEnd = E->designators_rend();
2110 D != DEnd; ++D) {
2111 if (D->isFieldDesignator()) {
2112 if (FieldDecl *Field = D->getField())
2113 AddMemberRef(Field, D->getFieldLoc());
2114 continue;
2115 }
2116 if (D->isArrayDesignator()) {
2117 AddStmt(E->getArrayIndex(*D));
2118 continue;
2119 }
2120 assert(D->isArrayRangeDesignator() && "Unknown designator kind");
2121 AddStmt(E->getArrayRangeEnd(*D));
2122 AddStmt(E->getArrayRangeStart(*D));
2123 }
2124}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002125void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002126 EnqueueChildren(E);
2127 AddTypeLoc(E->getTypeInfoAsWritten());
2128}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002129void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002130 AddStmt(FS->getBody());
2131 AddStmt(FS->getInc());
2132 AddStmt(FS->getCond());
2133 AddDecl(FS->getConditionVariable());
2134 AddStmt(FS->getInit());
2135}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002136void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002137 WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
2138}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002139void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002140 AddStmt(If->getElse());
2141 AddStmt(If->getThen());
2142 AddStmt(If->getCond());
2143 AddDecl(If->getConditionVariable());
2144}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002145void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002146 // We care about the syntactic form of the initializer list, only.
2147 if (InitListExpr *Syntactic = IE->getSyntacticForm())
2148 IE = Syntactic;
2149 EnqueueChildren(IE);
2150}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002151void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002152 WL.push_back(MemberExprParts(M, Parent));
2153
2154 // If the base of the member access expression is an implicit 'this', don't
2155 // visit it.
2156 // FIXME: If we ever want to show these implicit accesses, this will be
2157 // unfortunate. However, clang_getCursor() relies on this behavior.
2158 if (!M->isImplicitAccess())
2159 AddStmt(M->getBase());
2160}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002161void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002162 AddTypeLoc(E->getEncodedTypeSourceInfo());
2163}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002164void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002165 EnqueueChildren(M);
2166 AddTypeLoc(M->getClassReceiverTypeInfo());
2167}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002168void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002169 // Visit the components of the offsetof expression.
2170 for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
2171 typedef OffsetOfExpr::OffsetOfNode OffsetOfNode;
2172 const OffsetOfNode &Node = E->getComponent(I-1);
2173 switch (Node.getKind()) {
2174 case OffsetOfNode::Array:
2175 AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
2176 break;
2177 case OffsetOfNode::Field:
2178 AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
2179 break;
2180 case OffsetOfNode::Identifier:
2181 case OffsetOfNode::Base:
2182 continue;
2183 }
2184 }
2185 // Visit the type into which we're computing the offset.
2186 AddTypeLoc(E->getTypeSourceInfo());
2187}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002188void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002189 AddExplicitTemplateArgs(E->getOptionalExplicitTemplateArgs());
2190 WL.push_back(OverloadExprParts(E, Parent));
2191}
2192void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002193 const UnaryExprOrTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002194 EnqueueChildren(E);
2195 if (E->isArgumentType())
2196 AddTypeLoc(E->getArgumentTypeInfo());
2197}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002198void EnqueueVisitor::VisitStmt(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002199 EnqueueChildren(S);
2200}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002201void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002202 AddStmt(S->getBody());
2203 AddStmt(S->getCond());
2204 AddDecl(S->getConditionVariable());
2205}
2206
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002207void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002208 AddStmt(W->getBody());
2209 AddStmt(W->getCond());
2210 AddDecl(W->getConditionVariable());
2211}
2212
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002213void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002214 for (unsigned I = E->getNumArgs(); I > 0; --I)
2215 AddTypeLoc(E->getArg(I-1));
2216}
2217
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002218void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002219 AddTypeLoc(E->getQueriedTypeSourceInfo());
2220}
2221
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002222void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002223 EnqueueChildren(E);
2224}
2225
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002226void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002227 VisitOverloadExpr(U);
2228 if (!U->isImplicitAccess())
2229 AddStmt(U->getBase());
2230}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002231void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002232 AddStmt(E->getSubExpr());
2233 AddTypeLoc(E->getWrittenTypeInfo());
2234}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002235void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002236 WL.push_back(SizeOfPackExprParts(E, Parent));
2237}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002238void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002239 // If the opaque value has a source expression, just transparently
2240 // visit that. This is useful for (e.g.) pseudo-object expressions.
2241 if (Expr *SourceExpr = E->getSourceExpr())
2242 return Visit(SourceExpr);
2243}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002244void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002245 AddStmt(E->getBody());
2246 WL.push_back(LambdaExprParts(E, Parent));
2247}
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002248void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002249 // Treat the expression like its syntactic form.
2250 Visit(E->getSyntacticForm());
2251}
2252
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00002253void EnqueueVisitor::VisitOMPExecutableDirective(
2254 const OMPExecutableDirective *D) {
2255 EnqueueChildren(D);
2256 for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
2257 E = D->clauses().end();
2258 I != E; ++I)
2259 EnqueueChildren(*I);
2260}
2261
2262void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
2263 VisitOMPExecutableDirective(D);
2264}
2265
Alexey Bataev1b59ab52014-02-27 08:29:12 +00002266void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
2267 VisitOMPExecutableDirective(D);
2268}
2269
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002270void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002271 EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU,RegionOfInterest)).Visit(S);
2272}
2273
2274bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
2275 if (RegionOfInterest.isValid()) {
2276 SourceRange Range = getRawCursorExtent(C);
2277 if (Range.isInvalid() || CompareRegionOfInterest(Range))
2278 return false;
2279 }
2280 return true;
2281}
2282
2283bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
2284 while (!WL.empty()) {
2285 // Dequeue the worklist item.
Robert Wilhelm25284cc2013-08-23 16:11:15 +00002286 VisitorJob LI = WL.pop_back_val();
Guy Benyei11169dd2012-12-18 14:30:41 +00002287
2288 // Set the Parent field, then back to its old value once we're done.
2289 SetParentRAII SetParent(Parent, StmtParent, LI.getParent());
2290
2291 switch (LI.getKind()) {
2292 case VisitorJob::DeclVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002293 const Decl *D = cast<DeclVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002294 if (!D)
2295 continue;
2296
2297 // For now, perform default visitation for Decls.
2298 if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
2299 cast<DeclVisit>(&LI)->isFirst())))
2300 return true;
2301
2302 continue;
2303 }
2304 case VisitorJob::ExplicitTemplateArgsVisitKind: {
2305 const ASTTemplateArgumentListInfo *ArgList =
2306 cast<ExplicitTemplateArgsVisit>(&LI)->get();
2307 for (const TemplateArgumentLoc *Arg = ArgList->getTemplateArgs(),
2308 *ArgEnd = Arg + ArgList->NumTemplateArgs;
2309 Arg != ArgEnd; ++Arg) {
2310 if (VisitTemplateArgumentLoc(*Arg))
2311 return true;
2312 }
2313 continue;
2314 }
2315 case VisitorJob::TypeLocVisitKind: {
2316 // Perform default visitation for TypeLocs.
2317 if (Visit(cast<TypeLocVisit>(&LI)->get()))
2318 return true;
2319 continue;
2320 }
2321 case VisitorJob::LabelRefVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002322 const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002323 if (LabelStmt *stmt = LS->getStmt()) {
2324 if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
2325 TU))) {
2326 return true;
2327 }
2328 }
2329 continue;
2330 }
2331
2332 case VisitorJob::NestedNameSpecifierLocVisitKind: {
2333 NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
2334 if (VisitNestedNameSpecifierLoc(V->get()))
2335 return true;
2336 continue;
2337 }
2338
2339 case VisitorJob::DeclarationNameInfoVisitKind: {
2340 if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)
2341 ->get()))
2342 return true;
2343 continue;
2344 }
2345 case VisitorJob::MemberRefVisitKind: {
2346 MemberRefVisit *V = cast<MemberRefVisit>(&LI);
2347 if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
2348 return true;
2349 continue;
2350 }
2351 case VisitorJob::StmtVisitKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002352 const Stmt *S = cast<StmtVisit>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002353 if (!S)
2354 continue;
2355
2356 // Update the current cursor.
2357 CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
2358 if (!IsInRegionOfInterest(Cursor))
2359 continue;
2360 switch (Visitor(Cursor, Parent, ClientData)) {
2361 case CXChildVisit_Break: return true;
2362 case CXChildVisit_Continue: break;
2363 case CXChildVisit_Recurse:
2364 if (PostChildrenVisitor)
2365 WL.push_back(PostChildrenVisit(0, Cursor));
2366 EnqueueWorkList(WL, S);
2367 break;
2368 }
2369 continue;
2370 }
2371 case VisitorJob::MemberExprPartsKind: {
2372 // Handle the other pieces in the MemberExpr besides the base.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002373 const MemberExpr *M = cast<MemberExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002374
2375 // Visit the nested-name-specifier
2376 if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
2377 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2378 return true;
2379
2380 // Visit the declaration name.
2381 if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
2382 return true;
2383
2384 // Visit the explicitly-specified template arguments, if any.
2385 if (M->hasExplicitTemplateArgs()) {
2386 for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
2387 *ArgEnd = Arg + M->getNumTemplateArgs();
2388 Arg != ArgEnd; ++Arg) {
2389 if (VisitTemplateArgumentLoc(*Arg))
2390 return true;
2391 }
2392 }
2393 continue;
2394 }
2395 case VisitorJob::DeclRefExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002396 const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002397 // Visit nested-name-specifier, if present.
2398 if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
2399 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2400 return true;
2401 // Visit declaration name.
2402 if (VisitDeclarationNameInfo(DR->getNameInfo()))
2403 return true;
2404 continue;
2405 }
2406 case VisitorJob::OverloadExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002407 const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002408 // Visit the nested-name-specifier.
2409 if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
2410 if (VisitNestedNameSpecifierLoc(QualifierLoc))
2411 return true;
2412 // Visit the declaration name.
2413 if (VisitDeclarationNameInfo(O->getNameInfo()))
2414 return true;
2415 // Visit the overloaded declaration reference.
2416 if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
2417 return true;
2418 continue;
2419 }
2420 case VisitorJob::SizeOfPackExprPartsKind: {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002421 const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002422 NamedDecl *Pack = E->getPack();
2423 if (isa<TemplateTypeParmDecl>(Pack)) {
2424 if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
2425 E->getPackLoc(), TU)))
2426 return true;
2427
2428 continue;
2429 }
2430
2431 if (isa<TemplateTemplateParmDecl>(Pack)) {
2432 if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
2433 E->getPackLoc(), TU)))
2434 return true;
2435
2436 continue;
2437 }
2438
2439 // Non-type template parameter packs and function parameter packs are
2440 // treated like DeclRefExpr cursors.
2441 continue;
2442 }
2443
2444 case VisitorJob::LambdaExprPartsKind: {
2445 // Visit captures.
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002446 const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
Guy Benyei11169dd2012-12-18 14:30:41 +00002447 for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
2448 CEnd = E->explicit_capture_end();
2449 C != CEnd; ++C) {
Richard Smithba71c082013-05-16 06:20:58 +00002450 // FIXME: Lambda init-captures.
2451 if (!C->capturesVariable())
Guy Benyei11169dd2012-12-18 14:30:41 +00002452 continue;
Richard Smithba71c082013-05-16 06:20:58 +00002453
Guy Benyei11169dd2012-12-18 14:30:41 +00002454 if (Visit(MakeCursorVariableRef(C->getCapturedVar(),
2455 C->getLocation(),
2456 TU)))
2457 return true;
2458 }
2459
2460 // Visit parameters and return type, if present.
2461 if (E->hasExplicitParameters() || E->hasExplicitResultType()) {
2462 TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2463 if (E->hasExplicitParameters() && E->hasExplicitResultType()) {
2464 // Visit the whole type.
2465 if (Visit(TL))
2466 return true;
David Blaikie6adc78e2013-02-18 22:06:02 +00002467 } else if (FunctionProtoTypeLoc Proto =
2468 TL.getAs<FunctionProtoTypeLoc>()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002469 if (E->hasExplicitParameters()) {
2470 // Visit parameters.
Alp Tokerb3fd5cf2014-01-21 00:32:38 +00002471 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2472 if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
Guy Benyei11169dd2012-12-18 14:30:41 +00002473 return true;
2474 } else {
2475 // Visit result type.
Alp Toker42a16a62014-01-25 23:51:36 +00002476 if (Visit(Proto.getReturnLoc()))
Guy Benyei11169dd2012-12-18 14:30:41 +00002477 return true;
2478 }
2479 }
2480 }
2481 break;
2482 }
2483
2484 case VisitorJob::PostChildrenVisitKind:
2485 if (PostChildrenVisitor(Parent, ClientData))
2486 return true;
2487 break;
2488 }
2489 }
2490 return false;
2491}
2492
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00002493bool CursorVisitor::Visit(const Stmt *S) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002494 VisitorWorkList *WL = 0;
2495 if (!WorkListFreeList.empty()) {
2496 WL = WorkListFreeList.back();
2497 WL->clear();
2498 WorkListFreeList.pop_back();
2499 }
2500 else {
2501 WL = new VisitorWorkList();
2502 WorkListCache.push_back(WL);
2503 }
2504 EnqueueWorkList(*WL, S);
2505 bool result = RunVisitorWorkList(*WL);
2506 WorkListFreeList.push_back(WL);
2507 return result;
2508}
2509
2510namespace {
Dmitri Gribenkof8579502013-01-12 19:30:44 +00002511typedef SmallVector<SourceRange, 4> RefNamePieces;
Guy Benyei11169dd2012-12-18 14:30:41 +00002512RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
2513 const DeclarationNameInfo &NI,
2514 const SourceRange &QLoc,
2515 const ASTTemplateArgumentListInfo *TemplateArgs = 0){
2516 const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
2517 const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
2518 const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;
2519
2520 const DeclarationName::NameKind Kind = NI.getName().getNameKind();
2521
2522 RefNamePieces Pieces;
2523
2524 if (WantQualifier && QLoc.isValid())
2525 Pieces.push_back(QLoc);
2526
2527 if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
2528 Pieces.push_back(NI.getLoc());
2529
2530 if (WantTemplateArgs && TemplateArgs)
2531 Pieces.push_back(SourceRange(TemplateArgs->LAngleLoc,
2532 TemplateArgs->RAngleLoc));
2533
2534 if (Kind == DeclarationName::CXXOperatorName) {
2535 Pieces.push_back(SourceLocation::getFromRawEncoding(
2536 NI.getInfo().CXXOperatorName.BeginOpNameLoc));
2537 Pieces.push_back(SourceLocation::getFromRawEncoding(
2538 NI.getInfo().CXXOperatorName.EndOpNameLoc));
2539 }
2540
2541 if (WantSinglePiece) {
2542 SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
2543 Pieces.clear();
2544 Pieces.push_back(R);
2545 }
2546
2547 return Pieces;
2548}
2549}
2550
2551//===----------------------------------------------------------------------===//
2552// Misc. API hooks.
2553//===----------------------------------------------------------------------===//
2554
2555static llvm::sys::Mutex EnableMultithreadingMutex;
2556static bool EnabledMultithreading;
2557
Chad Rosier05c71aa2013-03-27 18:28:23 +00002558static void fatal_error_handler(void *user_data, const std::string& reason,
2559 bool gen_crash_diag) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002560 // Write the result out to stderr avoiding errs() because raw_ostreams can
2561 // call report_fatal_error.
2562 fprintf(stderr, "LIBCLANG FATAL ERROR: %s\n", reason.c_str());
2563 ::abort();
2564}
2565
2566extern "C" {
2567CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
2568 int displayDiagnostics) {
Guy Benyei11169dd2012-12-18 14:30:41 +00002569 // We use crash recovery to make some of our APIs more reliable, implicitly
2570 // enable it.
Argyrios Kyrtzidis3701f542013-11-27 08:58:09 +00002571 if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
2572 llvm::CrashRecoveryContext::Enable();
Guy Benyei11169dd2012-12-18 14:30:41 +00002573
2574 // Enable support for multithreading in LLVM.
2575 {
2576 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
2577 if (!EnabledMultithreading) {
2578 llvm::install_fatal_error_handler(fatal_error_handler, 0);
2579 llvm::llvm_start_multithreaded();
2580 EnabledMultithreading = true;
2581 }
2582 }
2583
2584 CIndexer *CIdxr = new CIndexer();
2585 if (excludeDeclarationsFromPCH)
2586 CIdxr->setOnlyLocalDecls();
2587 if (displayDiagnostics)
2588 CIdxr->setDisplayDiagnostics();
2589
2590 if (getenv("LIBCLANG_BGPRIO_INDEX"))
2591 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2592 CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
2593 if (getenv("LIBCLANG_BGPRIO_EDIT"))
2594 CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
2595 CXGlobalOpt_ThreadBackgroundPriorityForEditing);
2596
2597 return CIdxr;
2598}
2599
2600void clang_disposeIndex(CXIndex CIdx) {
2601 if (CIdx)
2602 delete static_cast<CIndexer *>(CIdx);
2603}
2604
2605void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
2606 if (CIdx)
2607 static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
2608}
2609
2610unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
2611 if (CIdx)
2612 return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
2613 return 0;
2614}
2615
2616void clang_toggleCrashRecovery(unsigned isEnabled) {
2617 if (isEnabled)
2618 llvm::CrashRecoveryContext::Enable();
2619 else
2620 llvm::CrashRecoveryContext::Disable();
2621}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002622
Guy Benyei11169dd2012-12-18 14:30:41 +00002623CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
2624 const char *ast_filename) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002625 CXTranslationUnit TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002626 enum CXErrorCode Result =
2627 clang_createTranslationUnit2(CIdx, ast_filename, &TU);
Reid Klecknerfd48fc62014-02-12 23:56:20 +00002628 (void)Result;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002629 assert((TU && Result == CXError_Success) ||
2630 (!TU && Result != CXError_Success));
2631 return TU;
2632}
2633
2634enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
2635 const char *ast_filename,
2636 CXTranslationUnit *out_TU) {
Dmitri Gribenko8850cda2014-02-19 10:24:00 +00002637 if (out_TU)
2638 *out_TU = NULL;
2639
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002640 if (!CIdx || !ast_filename || !out_TU)
2641 return CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002642
Argyrios Kyrtzidis27021012013-05-24 22:24:07 +00002643 LOG_FUNC_SECTION {
2644 *Log << ast_filename;
2645 }
2646
Guy Benyei11169dd2012-12-18 14:30:41 +00002647 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2648 FileSystemOptions FileSystemOpts;
2649
2650 IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002651 ASTUnit *AU = ASTUnit::LoadFromASTFile(ast_filename, Diags, FileSystemOpts,
Dmitri Gribenko2febd212014-02-07 15:00:22 +00002652 CXXIdx->getOnlyLocalDecls(), None,
2653 /*CaptureDiagnostics=*/true,
2654 /*AllowPCHWithCompilerErrors=*/true,
2655 /*UserFilesAreVolatile=*/true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002656 *out_TU = MakeCXTranslationUnit(CXXIdx, AU);
2657 return *out_TU ? CXError_Success : CXError_Failure;
Guy Benyei11169dd2012-12-18 14:30:41 +00002658}
2659
2660unsigned clang_defaultEditingTranslationUnitOptions() {
2661 return CXTranslationUnit_PrecompiledPreamble |
2662 CXTranslationUnit_CacheCompletionResults;
2663}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002664
Guy Benyei11169dd2012-12-18 14:30:41 +00002665CXTranslationUnit
2666clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
2667 const char *source_filename,
2668 int num_command_line_args,
2669 const char * const *command_line_args,
2670 unsigned num_unsaved_files,
2671 struct CXUnsavedFile *unsaved_files) {
2672 unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
2673 return clang_parseTranslationUnit(CIdx, source_filename,
2674 command_line_args, num_command_line_args,
2675 unsaved_files, num_unsaved_files,
2676 Options);
2677}
2678
2679struct ParseTranslationUnitInfo {
2680 CXIndex CIdx;
2681 const char *source_filename;
2682 const char *const *command_line_args;
2683 int num_command_line_args;
2684 struct CXUnsavedFile *unsaved_files;
2685 unsigned num_unsaved_files;
2686 unsigned options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002687 CXTranslationUnit *out_TU;
2688 CXErrorCode result;
Guy Benyei11169dd2012-12-18 14:30:41 +00002689};
2690static void clang_parseTranslationUnit_Impl(void *UserData) {
2691 ParseTranslationUnitInfo *PTUI =
2692 static_cast<ParseTranslationUnitInfo*>(UserData);
2693 CXIndex CIdx = PTUI->CIdx;
2694 const char *source_filename = PTUI->source_filename;
2695 const char * const *command_line_args = PTUI->command_line_args;
2696 int num_command_line_args = PTUI->num_command_line_args;
2697 struct CXUnsavedFile *unsaved_files = PTUI->unsaved_files;
2698 unsigned num_unsaved_files = PTUI->num_unsaved_files;
2699 unsigned options = PTUI->options;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002700 CXTranslationUnit *out_TU = PTUI->out_TU;
Guy Benyei11169dd2012-12-18 14:30:41 +00002701
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002702 // Set up the initial return values.
2703 if (out_TU)
2704 *out_TU = NULL;
2705 PTUI->result = CXError_Failure;
2706
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002707 // Check arguments.
2708 if (!CIdx || !out_TU ||
2709 (unsaved_files == NULL && num_unsaved_files != 0)) {
2710 PTUI->result = CXError_InvalidArguments;
Guy Benyei11169dd2012-12-18 14:30:41 +00002711 return;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002712 }
2713
Guy Benyei11169dd2012-12-18 14:30:41 +00002714 CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
2715
2716 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2717 setThreadBackgroundPriority();
2718
2719 bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
2720 // FIXME: Add a flag for modules.
2721 TranslationUnitKind TUKind
2722 = (options & CXTranslationUnit_Incomplete)? TU_Prefix : TU_Complete;
Alp Toker8c8a8752013-12-03 06:53:35 +00002723 bool CacheCodeCompletionResults
Guy Benyei11169dd2012-12-18 14:30:41 +00002724 = options & CXTranslationUnit_CacheCompletionResults;
2725 bool IncludeBriefCommentsInCodeCompletion
2726 = options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
2727 bool SkipFunctionBodies = options & CXTranslationUnit_SkipFunctionBodies;
2728 bool ForSerialization = options & CXTranslationUnit_ForSerialization;
2729
2730 // Configure the diagnostics.
2731 IntrusiveRefCntPtr<DiagnosticsEngine>
Sean Silvaf1b49e22013-01-20 01:58:28 +00002732 Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions));
Guy Benyei11169dd2012-12-18 14:30:41 +00002733
2734 // Recover resources if we crash before exiting this function.
2735 llvm::CrashRecoveryContextCleanupRegistrar<DiagnosticsEngine,
2736 llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
2737 DiagCleanup(Diags.getPtr());
2738
Ahmed Charlesb8984322014-03-07 20:03:18 +00002739 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
2740 new std::vector<ASTUnit::RemappedFile>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002741
2742 // Recover resources if we crash before exiting this function.
2743 llvm::CrashRecoveryContextCleanupRegistrar<
2744 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
2745
2746 for (unsigned I = 0; I != num_unsaved_files; ++I) {
2747 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
2748 const llvm::MemoryBuffer *Buffer
2749 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
2750 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
2751 Buffer));
2752 }
2753
Ahmed Charlesb8984322014-03-07 20:03:18 +00002754 std::unique_ptr<std::vector<const char *>> Args(
2755 new std::vector<const char *>());
Guy Benyei11169dd2012-12-18 14:30:41 +00002756
2757 // Recover resources if we crash before exiting this method.
2758 llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char*> >
2759 ArgsCleanup(Args.get());
2760
2761 // Since the Clang C library is primarily used by batch tools dealing with
2762 // (often very broken) source code, where spell-checking can have a
2763 // significant negative impact on performance (particularly when
2764 // precompiled headers are involved), we disable it by default.
2765 // Only do this if we haven't found a spell-checking-related argument.
2766 bool FoundSpellCheckingArgument = false;
2767 for (int I = 0; I != num_command_line_args; ++I) {
2768 if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
2769 strcmp(command_line_args[I], "-fspell-checking") == 0) {
2770 FoundSpellCheckingArgument = true;
2771 break;
2772 }
2773 }
2774 if (!FoundSpellCheckingArgument)
2775 Args->push_back("-fno-spell-checking");
2776
2777 Args->insert(Args->end(), command_line_args,
2778 command_line_args + num_command_line_args);
2779
2780 // The 'source_filename' argument is optional. If the caller does not
2781 // specify it then it is assumed that the source file is specified
2782 // in the actual argument list.
2783 // Put the source file after command_line_args otherwise if '-x' flag is
2784 // present it will be unused.
2785 if (source_filename)
2786 Args->push_back(source_filename);
2787
2788 // Do we need the detailed preprocessing record?
2789 if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
2790 Args->push_back("-Xclang");
2791 Args->push_back("-detailed-preprocessing-record");
2792 }
2793
2794 unsigned NumErrors = Diags->getClient()->getNumErrors();
Ahmed Charlesb8984322014-03-07 20:03:18 +00002795 std::unique_ptr<ASTUnit> ErrUnit;
2796 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
Dmitri Gribenko340dd512014-03-12 15:35:53 +00002797 Args->data(), Args->data() + Args->size(), Diags,
Ahmed Charlesb8984322014-03-07 20:03:18 +00002798 CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
2799 /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
2800 /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
2801 CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
2802 /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies,
2803 /*UserFilesAreVolatile=*/true, ForSerialization, &ErrUnit));
Guy Benyei11169dd2012-12-18 14:30:41 +00002804
2805 if (NumErrors != Diags->getClient()->getNumErrors()) {
2806 // Make sure to check that 'Unit' is non-NULL.
2807 if (CXXIdx->getDisplayDiagnostics())
2808 printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
2809 }
2810
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002811 if (isASTReadError(Unit ? Unit.get() : ErrUnit.get())) {
2812 PTUI->result = CXError_ASTReadError;
2813 } else {
Ahmed Charles9a16beb2014-03-07 19:33:25 +00002814 *PTUI->out_TU = MakeCXTranslationUnit(CXXIdx, Unit.release());
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002815 PTUI->result = *PTUI->out_TU ? CXError_Success : CXError_Failure;
2816 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002817}
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002818
2819CXTranslationUnit
2820clang_parseTranslationUnit(CXIndex CIdx,
2821 const char *source_filename,
2822 const char *const *command_line_args,
2823 int num_command_line_args,
2824 struct CXUnsavedFile *unsaved_files,
2825 unsigned num_unsaved_files,
2826 unsigned options) {
2827 CXTranslationUnit TU;
2828 enum CXErrorCode Result = clang_parseTranslationUnit2(
2829 CIdx, source_filename, command_line_args, num_command_line_args,
2830 unsaved_files, num_unsaved_files, options, &TU);
Reid Kleckner6eaf05a2014-02-13 01:19:59 +00002831 (void)Result;
Dmitri Gribenko1bf8d912014-02-18 15:20:02 +00002832 assert((TU && Result == CXError_Success) ||
2833 (!TU && Result != CXError_Success));
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002834 return TU;
2835}
2836
2837enum CXErrorCode clang_parseTranslationUnit2(
2838 CXIndex CIdx,
2839 const char *source_filename,
2840 const char *const *command_line_args,
2841 int num_command_line_args,
2842 struct CXUnsavedFile *unsaved_files,
2843 unsigned num_unsaved_files,
2844 unsigned options,
2845 CXTranslationUnit *out_TU) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002846 LOG_FUNC_SECTION {
2847 *Log << source_filename << ": ";
2848 for (int i = 0; i != num_command_line_args; ++i)
2849 *Log << command_line_args[i] << " ";
2850 }
2851
Guy Benyei11169dd2012-12-18 14:30:41 +00002852 ParseTranslationUnitInfo PTUI = { CIdx, source_filename, command_line_args,
2853 num_command_line_args, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002854 num_unsaved_files, options, out_TU,
2855 CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00002856 llvm::CrashRecoveryContext CRC;
2857
2858 if (!RunSafely(CRC, clang_parseTranslationUnit_Impl, &PTUI)) {
2859 fprintf(stderr, "libclang: crash detected during parsing: {\n");
2860 fprintf(stderr, " 'source_filename' : '%s'\n", source_filename);
2861 fprintf(stderr, " 'command_line_args' : [");
2862 for (int i = 0; i != num_command_line_args; ++i) {
2863 if (i)
2864 fprintf(stderr, ", ");
2865 fprintf(stderr, "'%s'", command_line_args[i]);
2866 }
2867 fprintf(stderr, "],\n");
2868 fprintf(stderr, " 'unsaved_files' : [");
2869 for (unsigned i = 0; i != num_unsaved_files; ++i) {
2870 if (i)
2871 fprintf(stderr, ", ");
2872 fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
2873 unsaved_files[i].Length);
2874 }
2875 fprintf(stderr, "],\n");
2876 fprintf(stderr, " 'options' : %d,\n", options);
2877 fprintf(stderr, "}\n");
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002878
2879 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00002880 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002881 if (CXTranslationUnit *TU = PTUI.out_TU)
2882 PrintLibclangResourceUsage(*TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002883 }
2884
2885 return PTUI.result;
2886}
2887
2888unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
2889 return CXSaveTranslationUnit_None;
2890}
2891
2892namespace {
2893
2894struct SaveTranslationUnitInfo {
2895 CXTranslationUnit TU;
2896 const char *FileName;
2897 unsigned options;
2898 CXSaveError result;
2899};
2900
2901}
2902
2903static void clang_saveTranslationUnit_Impl(void *UserData) {
2904 SaveTranslationUnitInfo *STUI =
2905 static_cast<SaveTranslationUnitInfo*>(UserData);
2906
Dmitri Gribenko183436e2013-01-26 21:49:50 +00002907 CIndexer *CXXIdx = STUI->TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00002908 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
2909 setThreadBackgroundPriority();
2910
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002911 bool hadError = cxtu::getASTUnit(STUI->TU)->Save(STUI->FileName);
Guy Benyei11169dd2012-12-18 14:30:41 +00002912 STUI->result = hadError ? CXSaveError_Unknown : CXSaveError_None;
2913}
2914
2915int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
2916 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00002917 LOG_FUNC_SECTION {
2918 *Log << TU << ' ' << FileName;
2919 }
2920
Dmitri Gribenko852d6222014-02-11 15:02:48 +00002921 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002922 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002923 return CXSaveError_InvalidTU;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002924 }
Guy Benyei11169dd2012-12-18 14:30:41 +00002925
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002926 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00002927 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
2928 if (!CXXUnit->hasSema())
2929 return CXSaveError_InvalidTU;
2930
2931 SaveTranslationUnitInfo STUI = { TU, FileName, options, CXSaveError_None };
2932
2933 if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred() ||
2934 getenv("LIBCLANG_NOTHREADS")) {
2935 clang_saveTranslationUnit_Impl(&STUI);
2936
2937 if (getenv("LIBCLANG_RESOURCE_USAGE"))
2938 PrintLibclangResourceUsage(TU);
2939
2940 return STUI.result;
2941 }
2942
2943 // We have an AST that has invalid nodes due to compiler errors.
2944 // Use a crash recovery thread for protection.
2945
2946 llvm::CrashRecoveryContext CRC;
2947
2948 if (!RunSafely(CRC, clang_saveTranslationUnit_Impl, &STUI)) {
2949 fprintf(stderr, "libclang: crash detected during AST saving: {\n");
2950 fprintf(stderr, " 'filename' : '%s'\n", FileName);
2951 fprintf(stderr, " 'options' : %d,\n", options);
2952 fprintf(stderr, "}\n");
2953
2954 return CXSaveError_Unknown;
2955
2956 } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
2957 PrintLibclangResourceUsage(TU);
2958 }
2959
2960 return STUI.result;
2961}
2962
2963void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
2964 if (CTUnit) {
2965 // If the translation unit has been marked as unsafe to free, just discard
2966 // it.
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002967 ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
2968 if (Unit && Unit->isUnsafeToFree())
Guy Benyei11169dd2012-12-18 14:30:41 +00002969 return;
2970
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00002971 delete cxtu::getASTUnit(CTUnit);
Dmitri Gribenkob95b3f12013-01-26 22:44:19 +00002972 delete CTUnit->StringPool;
Guy Benyei11169dd2012-12-18 14:30:41 +00002973 delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
2974 disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
Dmitri Gribenko9e605112013-11-13 22:16:51 +00002975 delete CTUnit->CommentToXML;
Guy Benyei11169dd2012-12-18 14:30:41 +00002976 delete CTUnit;
2977 }
2978}
2979
2980unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
2981 return CXReparse_None;
2982}
2983
2984struct ReparseTranslationUnitInfo {
2985 CXTranslationUnit TU;
2986 unsigned num_unsaved_files;
2987 struct CXUnsavedFile *unsaved_files;
2988 unsigned options;
2989 int result;
2990};
2991
2992static void clang_reparseTranslationUnit_Impl(void *UserData) {
2993 ReparseTranslationUnitInfo *RTUI =
2994 static_cast<ReparseTranslationUnitInfo*>(UserData);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002995 RTUI->result = CXError_Failure;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00002996
Guy Benyei11169dd2012-12-18 14:30:41 +00002997 CXTranslationUnit TU = RTUI->TU;
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00002998 unsigned num_unsaved_files = RTUI->num_unsaved_files;
2999 struct CXUnsavedFile *unsaved_files = RTUI->unsaved_files;
3000 unsigned options = RTUI->options;
3001 (void) options;
3002
3003 // Check arguments.
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003004 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003005 LOG_BAD_TU(TU);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003006 RTUI->result = CXError_InvalidArguments;
3007 return;
3008 }
3009 if (unsaved_files == NULL && num_unsaved_files != 0) {
3010 RTUI->result = CXError_InvalidArguments;
Argyrios Kyrtzidisda4ba872013-01-16 18:13:00 +00003011 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003012 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003013
3014 // Reset the associated diagnostics.
3015 delete static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
3016 TU->Diagnostics = 0;
3017
Dmitri Gribenko183436e2013-01-26 21:49:50 +00003018 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00003019 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
3020 setThreadBackgroundPriority();
3021
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003022 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003023 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
Ahmed Charlesb8984322014-03-07 20:03:18 +00003024
3025 std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
3026 new std::vector<ASTUnit::RemappedFile>());
3027
Guy Benyei11169dd2012-12-18 14:30:41 +00003028 // Recover resources if we crash before exiting this function.
3029 llvm::CrashRecoveryContextCleanupRegistrar<
3030 std::vector<ASTUnit::RemappedFile> > RemappedCleanup(RemappedFiles.get());
3031
3032 for (unsigned I = 0; I != num_unsaved_files; ++I) {
3033 StringRef Data(unsaved_files[I].Contents, unsaved_files[I].Length);
3034 const llvm::MemoryBuffer *Buffer
3035 = llvm::MemoryBuffer::getMemBufferCopy(Data, unsaved_files[I].Filename);
3036 RemappedFiles->push_back(std::make_pair(unsaved_files[I].Filename,
3037 Buffer));
3038 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003039
Dmitri Gribenko2febd212014-02-07 15:00:22 +00003040 if (!CXXUnit->Reparse(*RemappedFiles.get()))
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003041 RTUI->result = CXError_Success;
3042 else if (isASTReadError(CXXUnit))
3043 RTUI->result = CXError_ASTReadError;
Guy Benyei11169dd2012-12-18 14:30:41 +00003044}
3045
3046int clang_reparseTranslationUnit(CXTranslationUnit TU,
3047 unsigned num_unsaved_files,
3048 struct CXUnsavedFile *unsaved_files,
3049 unsigned options) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00003050 LOG_FUNC_SECTION {
3051 *Log << TU;
3052 }
3053
Guy Benyei11169dd2012-12-18 14:30:41 +00003054 ReparseTranslationUnitInfo RTUI = { TU, num_unsaved_files, unsaved_files,
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003055 options, CXError_Failure };
Guy Benyei11169dd2012-12-18 14:30:41 +00003056
3057 if (getenv("LIBCLANG_NOTHREADS")) {
3058 clang_reparseTranslationUnit_Impl(&RTUI);
3059 return RTUI.result;
3060 }
3061
3062 llvm::CrashRecoveryContext CRC;
3063
3064 if (!RunSafely(CRC, clang_reparseTranslationUnit_Impl, &RTUI)) {
3065 fprintf(stderr, "libclang: crash detected during reparsing\n");
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003066 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00003067 return CXError_Crashed;
Guy Benyei11169dd2012-12-18 14:30:41 +00003068 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
3069 PrintLibclangResourceUsage(TU);
3070
3071 return RTUI.result;
3072}
3073
3074
3075CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003076 if (isNotUsableTU(CTUnit)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003077 LOG_BAD_TU(CTUnit);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003078 return cxstring::createEmpty();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003079 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003080
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003081 ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003082 return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003083}
3084
3085CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003086 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003087 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003088 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003089 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00003090
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003091 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003092 return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
3093}
3094
3095} // end: extern "C"
3096
3097//===----------------------------------------------------------------------===//
3098// CXFile Operations.
3099//===----------------------------------------------------------------------===//
3100
3101extern "C" {
3102CXString clang_getFileName(CXFile SFile) {
3103 if (!SFile)
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00003104 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00003105
3106 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003107 return cxstring::createRef(FEnt->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003108}
3109
3110time_t clang_getFileTime(CXFile SFile) {
3111 if (!SFile)
3112 return 0;
3113
3114 FileEntry *FEnt = static_cast<FileEntry *>(SFile);
3115 return FEnt->getModificationTime();
3116}
3117
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003118CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003119 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003120 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003121 return 0;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003122 }
Guy Benyei11169dd2012-12-18 14:30:41 +00003123
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003124 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003125
3126 FileManager &FMgr = CXXUnit->getFileManager();
3127 return const_cast<FileEntry *>(FMgr.getFile(file_name));
3128}
3129
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003130unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU,
3131 CXFile file) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00003132 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00003133 LOG_BAD_TU(TU);
3134 return 0;
3135 }
3136
3137 if (!file)
Guy Benyei11169dd2012-12-18 14:30:41 +00003138 return 0;
3139
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00003140 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00003141 FileEntry *FEnt = static_cast<FileEntry *>(file);
3142 return CXXUnit->getPreprocessor().getHeaderSearchInfo()
3143 .isFileMultipleIncludeGuarded(FEnt);
3144}
3145
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003146int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
3147 if (!file || !outID)
3148 return 1;
3149
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003150 FileEntry *FEnt = static_cast<FileEntry *>(file);
Rafael Espindolaf8f91b82013-08-01 21:42:11 +00003151 const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
3152 outID->data[0] = ID.getDevice();
3153 outID->data[1] = ID.getFile();
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003154 outID->data[2] = FEnt->getModificationTime();
3155 return 0;
Argyrios Kyrtzidisac08b262013-01-26 04:52:52 +00003156}
3157
Guy Benyei11169dd2012-12-18 14:30:41 +00003158} // end: extern "C"
3159
3160//===----------------------------------------------------------------------===//
3161// CXCursor Operations.
3162//===----------------------------------------------------------------------===//
3163
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003164static const Decl *getDeclFromExpr(const Stmt *E) {
3165 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003166 return getDeclFromExpr(CE->getSubExpr());
3167
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003168 if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003169 return RefExpr->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003170 if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003171 return ME->getMemberDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003172 if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003173 return RE->getDecl();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003174 if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003175 if (PRE->isExplicitProperty())
3176 return PRE->getExplicitProperty();
3177 // It could be messaging both getter and setter as in:
3178 // ++myobj.myprop;
3179 // in which case prefer to associate the setter since it is less obvious
3180 // from inspecting the source that the setter is going to get called.
3181 if (PRE->isMessagingSetter())
3182 return PRE->getImplicitPropertySetter();
3183 return PRE->getImplicitPropertyGetter();
3184 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003185 if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003186 return getDeclFromExpr(POE->getSyntacticForm());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003187 if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003188 if (Expr *Src = OVE->getSourceExpr())
3189 return getDeclFromExpr(Src);
3190
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003191 if (const CallExpr *CE = dyn_cast<CallExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003192 return getDeclFromExpr(CE->getCallee());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003193 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003194 if (!CE->isElidable())
3195 return CE->getConstructor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003196 if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003197 return OME->getMethodDecl();
3198
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003199 if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003200 return PE->getProtocol();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003201 if (const SubstNonTypeTemplateParmPackExpr *NTTP
Guy Benyei11169dd2012-12-18 14:30:41 +00003202 = dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
3203 return NTTP->getParameterPack();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003204 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003205 if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
3206 isa<ParmVarDecl>(SizeOfPack->getPack()))
3207 return SizeOfPack->getPack();
3208
3209 return 0;
3210}
3211
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003212static SourceLocation getLocationFromExpr(const Expr *E) {
3213 if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003214 return getLocationFromExpr(CE->getSubExpr());
3215
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003216 if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003217 return /*FIXME:*/Msg->getLeftLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003218 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003219 return DRE->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003220 if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003221 return Member->getMemberLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003222 if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003223 return Ivar->getLocation();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003224 if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003225 return SizeOfPack->getPackLoc();
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003226 if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00003227 return PropRef->getLocation();
3228
3229 return E->getLocStart();
3230}
3231
3232extern "C" {
3233
3234unsigned clang_visitChildren(CXCursor parent,
3235 CXCursorVisitor visitor,
3236 CXClientData client_data) {
3237 CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
3238 /*VisitPreprocessorLast=*/false);
3239 return CursorVis.VisitChildren(parent);
3240}
3241
3242#ifndef __has_feature
3243#define __has_feature(x) 0
3244#endif
3245#if __has_feature(blocks)
3246typedef enum CXChildVisitResult
3247 (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent);
3248
3249static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3250 CXClientData client_data) {
3251 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3252 return block(cursor, parent);
3253}
3254#else
3255// If we are compiled with a compiler that doesn't have native blocks support,
3256// define and call the block manually, so the
3257typedef struct _CXChildVisitResult
3258{
3259 void *isa;
3260 int flags;
3261 int reserved;
3262 enum CXChildVisitResult(*invoke)(struct _CXChildVisitResult*, CXCursor,
3263 CXCursor);
3264} *CXCursorVisitorBlock;
3265
3266static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
3267 CXClientData client_data) {
3268 CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
3269 return block->invoke(block, cursor, parent);
3270}
3271#endif
3272
3273
3274unsigned clang_visitChildrenWithBlock(CXCursor parent,
3275 CXCursorVisitorBlock block) {
3276 return clang_visitChildren(parent, visitWithBlock, block);
3277}
3278
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003279static CXString getDeclSpelling(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003280 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003281 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003282
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003283 const NamedDecl *ND = dyn_cast<NamedDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00003284 if (!ND) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003285 if (const ObjCPropertyImplDecl *PropImpl =
3286 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003287 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003288 return cxstring::createDup(Property->getIdentifier()->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003289
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003290 if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003291 if (Module *Mod = ImportD->getImportedModule())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003292 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003293
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003294 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003295 }
3296
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003297 if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003298 return cxstring::createDup(OMD->getSelector().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003299
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003300 if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
Guy Benyei11169dd2012-12-18 14:30:41 +00003301 // No, this isn't the same as the code below. getIdentifier() is non-virtual
3302 // and returns different names. NamedDecl returns the class name and
3303 // ObjCCategoryImplDecl returns the category name.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003304 return cxstring::createRef(CIMP->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003305
3306 if (isa<UsingDirectiveDecl>(D))
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003307 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003308
3309 SmallString<1024> S;
3310 llvm::raw_svector_ostream os(S);
3311 ND->printName(os);
3312
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003313 return cxstring::createDup(os.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003314}
3315
3316CXString clang_getCursorSpelling(CXCursor C) {
3317 if (clang_isTranslationUnit(C.kind))
Dmitri Gribenko2c173b42013-01-11 19:28:44 +00003318 return clang_getTranslationUnitSpelling(getCursorTU(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003319
3320 if (clang_isReference(C.kind)) {
3321 switch (C.kind) {
3322 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003323 const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003324 return cxstring::createRef(Super->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003325 }
3326 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003327 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003328 return cxstring::createRef(Class->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003329 }
3330 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003331 const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003332 assert(OID && "getCursorSpelling(): Missing protocol decl");
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003333 return cxstring::createRef(OID->getIdentifier()->getNameStart());
Guy Benyei11169dd2012-12-18 14:30:41 +00003334 }
3335 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003336 const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003337 return cxstring::createDup(B->getType().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003338 }
3339 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003340 const TypeDecl *Type = getCursorTypeRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003341 assert(Type && "Missing type decl");
3342
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003343 return cxstring::createDup(getCursorContext(C).getTypeDeclType(Type).
Guy Benyei11169dd2012-12-18 14:30:41 +00003344 getAsString());
3345 }
3346 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003347 const TemplateDecl *Template = getCursorTemplateRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003348 assert(Template && "Missing template decl");
3349
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003350 return cxstring::createDup(Template->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003351 }
3352
3353 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003354 const NamedDecl *NS = getCursorNamespaceRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003355 assert(NS && "Missing namespace decl");
3356
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003357 return cxstring::createDup(NS->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003358 }
3359
3360 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003361 const FieldDecl *Field = getCursorMemberRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003362 assert(Field && "Missing member decl");
3363
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003364 return cxstring::createDup(Field->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003365 }
3366
3367 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003368 const LabelStmt *Label = getCursorLabelRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003369 assert(Label && "Missing label");
3370
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003371 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003372 }
3373
3374 case CXCursor_OverloadedDeclRef: {
3375 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003376 if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
3377 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003378 return cxstring::createDup(ND->getNameAsString());
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003379 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003380 }
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003381 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003382 return cxstring::createDup(E->getName().getAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003383 OverloadedTemplateStorage *Ovl
3384 = Storage.get<OverloadedTemplateStorage*>();
3385 if (Ovl->size() == 0)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003386 return cxstring::createEmpty();
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003387 return cxstring::createDup((*Ovl->begin())->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003388 }
3389
3390 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00003391 const VarDecl *Var = getCursorVariableRef(C).first;
Guy Benyei11169dd2012-12-18 14:30:41 +00003392 assert(Var && "Missing variable decl");
3393
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003394 return cxstring::createDup(Var->getNameAsString());
Guy Benyei11169dd2012-12-18 14:30:41 +00003395 }
3396
3397 default:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003398 return cxstring::createRef("<not implemented>");
Guy Benyei11169dd2012-12-18 14:30:41 +00003399 }
3400 }
3401
3402 if (clang_isExpression(C.kind)) {
Argyrios Kyrtzidis3227d862014-03-03 19:40:52 +00003403 const Expr *E = getCursorExpr(C);
3404
3405 if (C.kind == CXCursor_ObjCStringLiteral ||
3406 C.kind == CXCursor_StringLiteral) {
3407 const StringLiteral *SLit;
3408 if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
3409 SLit = OSL->getString();
3410 } else {
3411 SLit = cast<StringLiteral>(E);
3412 }
3413 SmallString<256> Buf;
3414 llvm::raw_svector_ostream OS(Buf);
3415 SLit->outputString(OS);
3416 return cxstring::createDup(OS.str());
3417 }
3418
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003419 const Decl *D = getDeclFromExpr(getCursorExpr(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00003420 if (D)
3421 return getDeclSpelling(D);
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003422 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003423 }
3424
3425 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003426 const Stmt *S = getCursorStmt(C);
3427 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003428 return cxstring::createRef(Label->getName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003429
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003430 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003431 }
3432
3433 if (C.kind == CXCursor_MacroExpansion)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003434 return cxstring::createRef(getCursorMacroExpansion(C).getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003435 ->getNameStart());
3436
3437 if (C.kind == CXCursor_MacroDefinition)
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003438 return cxstring::createRef(getCursorMacroDefinition(C)->getName()
Guy Benyei11169dd2012-12-18 14:30:41 +00003439 ->getNameStart());
3440
3441 if (C.kind == CXCursor_InclusionDirective)
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003442 return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());
Guy Benyei11169dd2012-12-18 14:30:41 +00003443
3444 if (clang_isDeclaration(C.kind))
3445 return getDeclSpelling(getCursorDecl(C));
3446
3447 if (C.kind == CXCursor_AnnotateAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003448 const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003449 return cxstring::createDup(AA->getAnnotation());
Guy Benyei11169dd2012-12-18 14:30:41 +00003450 }
3451
3452 if (C.kind == CXCursor_AsmLabelAttr) {
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00003453 const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003454 return cxstring::createDup(AA->getLabel());
Guy Benyei11169dd2012-12-18 14:30:41 +00003455 }
3456
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003457 if (C.kind == CXCursor_PackedAttr) {
3458 return cxstring::createRef("packed");
3459 }
3460
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003461 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003462}
3463
3464CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
3465 unsigned pieceIndex,
3466 unsigned options) {
3467 if (clang_Cursor_isNull(C))
3468 return clang_getNullRange();
3469
3470 ASTContext &Ctx = getCursorContext(C);
3471
3472 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003473 const Stmt *S = getCursorStmt(C);
3474 if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003475 if (pieceIndex > 0)
3476 return clang_getNullRange();
3477 return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
3478 }
3479
3480 return clang_getNullRange();
3481 }
3482
3483 if (C.kind == CXCursor_ObjCMessageExpr) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00003484 if (const ObjCMessageExpr *
Guy Benyei11169dd2012-12-18 14:30:41 +00003485 ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
3486 if (pieceIndex >= ME->getNumSelectorLocs())
3487 return clang_getNullRange();
3488 return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
3489 }
3490 }
3491
3492 if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
3493 C.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003494 if (const ObjCMethodDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003495 MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
3496 if (pieceIndex >= MD->getNumSelectorLocs())
3497 return clang_getNullRange();
3498 return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
3499 }
3500 }
3501
3502 if (C.kind == CXCursor_ObjCCategoryDecl ||
3503 C.kind == CXCursor_ObjCCategoryImplDecl) {
3504 if (pieceIndex > 0)
3505 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003506 if (const ObjCCategoryDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003507 CD = dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
3508 return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003509 if (const ObjCCategoryImplDecl *
Guy Benyei11169dd2012-12-18 14:30:41 +00003510 CID = dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
3511 return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
3512 }
3513
3514 if (C.kind == CXCursor_ModuleImportDecl) {
3515 if (pieceIndex > 0)
3516 return clang_getNullRange();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003517 if (const ImportDecl *ImportD =
3518 dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003519 ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
3520 if (!Locs.empty())
3521 return cxloc::translateSourceRange(Ctx,
3522 SourceRange(Locs.front(), Locs.back()));
3523 }
3524 return clang_getNullRange();
3525 }
3526
3527 // FIXME: A CXCursor_InclusionDirective should give the location of the
3528 // filename, but we don't keep track of this.
3529
3530 // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
3531 // but we don't keep track of this.
3532
3533 // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
3534 // but we don't keep track of this.
3535
3536 // Default handling, give the location of the cursor.
3537
3538 if (pieceIndex > 0)
3539 return clang_getNullRange();
3540
3541 CXSourceLocation CXLoc = clang_getCursorLocation(C);
3542 SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
3543 return cxloc::translateSourceRange(Ctx, Loc);
3544}
3545
3546CXString clang_getCursorDisplayName(CXCursor C) {
3547 if (!clang_isDeclaration(C.kind))
3548 return clang_getCursorSpelling(C);
3549
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003550 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00003551 if (!D)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00003552 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00003553
3554 PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003555 if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00003556 D = FunTmpl->getTemplatedDecl();
3557
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003558 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003559 SmallString<64> Str;
3560 llvm::raw_svector_ostream OS(Str);
3561 OS << *Function;
3562 if (Function->getPrimaryTemplate())
3563 OS << "<>";
3564 OS << "(";
3565 for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
3566 if (I)
3567 OS << ", ";
3568 OS << Function->getParamDecl(I)->getType().getAsString(Policy);
3569 }
3570
3571 if (Function->isVariadic()) {
3572 if (Function->getNumParams())
3573 OS << ", ";
3574 OS << "...";
3575 }
3576 OS << ")";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003577 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003578 }
3579
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003580 if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00003581 SmallString<64> Str;
3582 llvm::raw_svector_ostream OS(Str);
3583 OS << *ClassTemplate;
3584 OS << "<";
3585 TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
3586 for (unsigned I = 0, N = Params->size(); I != N; ++I) {
3587 if (I)
3588 OS << ", ";
3589
3590 NamedDecl *Param = Params->getParam(I);
3591 if (Param->getIdentifier()) {
3592 OS << Param->getIdentifier()->getName();
3593 continue;
3594 }
3595
3596 // There is no parameter name, which makes this tricky. Try to come up
3597 // with something useful that isn't too long.
3598 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
3599 OS << (TTP->wasDeclaredWithTypename()? "typename" : "class");
3600 else if (NonTypeTemplateParmDecl *NTTP
3601 = dyn_cast<NonTypeTemplateParmDecl>(Param))
3602 OS << NTTP->getType().getAsString(Policy);
3603 else
3604 OS << "template<...> class";
3605 }
3606
3607 OS << ">";
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003608 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003609 }
3610
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003611 if (const ClassTemplateSpecializationDecl *ClassSpec
Guy Benyei11169dd2012-12-18 14:30:41 +00003612 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
3613 // If the type was explicitly written, use that.
3614 if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003615 return cxstring::createDup(TSInfo->getType().getAsString(Policy));
Guy Benyei11169dd2012-12-18 14:30:41 +00003616
Benjamin Kramer9170e912013-02-22 15:46:01 +00003617 SmallString<128> Str;
Guy Benyei11169dd2012-12-18 14:30:41 +00003618 llvm::raw_svector_ostream OS(Str);
3619 OS << *ClassSpec;
Benjamin Kramer9170e912013-02-22 15:46:01 +00003620 TemplateSpecializationType::PrintTemplateArgumentList(OS,
Guy Benyei11169dd2012-12-18 14:30:41 +00003621 ClassSpec->getTemplateArgs().data(),
3622 ClassSpec->getTemplateArgs().size(),
3623 Policy);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00003624 return cxstring::createDup(OS.str());
Guy Benyei11169dd2012-12-18 14:30:41 +00003625 }
3626
3627 return clang_getCursorSpelling(C);
3628}
3629
3630CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
3631 switch (Kind) {
3632 case CXCursor_FunctionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003633 return cxstring::createRef("FunctionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003634 case CXCursor_TypedefDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003635 return cxstring::createRef("TypedefDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003636 case CXCursor_EnumDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003637 return cxstring::createRef("EnumDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003638 case CXCursor_EnumConstantDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003639 return cxstring::createRef("EnumConstantDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003640 case CXCursor_StructDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003641 return cxstring::createRef("StructDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003642 case CXCursor_UnionDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003643 return cxstring::createRef("UnionDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003644 case CXCursor_ClassDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003645 return cxstring::createRef("ClassDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003646 case CXCursor_FieldDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003647 return cxstring::createRef("FieldDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003648 case CXCursor_VarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003649 return cxstring::createRef("VarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003650 case CXCursor_ParmDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003651 return cxstring::createRef("ParmDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003652 case CXCursor_ObjCInterfaceDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003653 return cxstring::createRef("ObjCInterfaceDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003654 case CXCursor_ObjCCategoryDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003655 return cxstring::createRef("ObjCCategoryDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003656 case CXCursor_ObjCProtocolDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003657 return cxstring::createRef("ObjCProtocolDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003658 case CXCursor_ObjCPropertyDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003659 return cxstring::createRef("ObjCPropertyDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003660 case CXCursor_ObjCIvarDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003661 return cxstring::createRef("ObjCIvarDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003662 case CXCursor_ObjCInstanceMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003663 return cxstring::createRef("ObjCInstanceMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003664 case CXCursor_ObjCClassMethodDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003665 return cxstring::createRef("ObjCClassMethodDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003666 case CXCursor_ObjCImplementationDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003667 return cxstring::createRef("ObjCImplementationDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003668 case CXCursor_ObjCCategoryImplDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003669 return cxstring::createRef("ObjCCategoryImplDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003670 case CXCursor_CXXMethod:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003671 return cxstring::createRef("CXXMethod");
Guy Benyei11169dd2012-12-18 14:30:41 +00003672 case CXCursor_UnexposedDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003673 return cxstring::createRef("UnexposedDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003674 case CXCursor_ObjCSuperClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003675 return cxstring::createRef("ObjCSuperClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003676 case CXCursor_ObjCProtocolRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003677 return cxstring::createRef("ObjCProtocolRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003678 case CXCursor_ObjCClassRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003679 return cxstring::createRef("ObjCClassRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003680 case CXCursor_TypeRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003681 return cxstring::createRef("TypeRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003682 case CXCursor_TemplateRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003683 return cxstring::createRef("TemplateRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003684 case CXCursor_NamespaceRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003685 return cxstring::createRef("NamespaceRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003686 case CXCursor_MemberRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003687 return cxstring::createRef("MemberRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003688 case CXCursor_LabelRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003689 return cxstring::createRef("LabelRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003690 case CXCursor_OverloadedDeclRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003691 return cxstring::createRef("OverloadedDeclRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003692 case CXCursor_VariableRef:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003693 return cxstring::createRef("VariableRef");
Guy Benyei11169dd2012-12-18 14:30:41 +00003694 case CXCursor_IntegerLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003695 return cxstring::createRef("IntegerLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003696 case CXCursor_FloatingLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003697 return cxstring::createRef("FloatingLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003698 case CXCursor_ImaginaryLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003699 return cxstring::createRef("ImaginaryLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003700 case CXCursor_StringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003701 return cxstring::createRef("StringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003702 case CXCursor_CharacterLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003703 return cxstring::createRef("CharacterLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003704 case CXCursor_ParenExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003705 return cxstring::createRef("ParenExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003706 case CXCursor_UnaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003707 return cxstring::createRef("UnaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003708 case CXCursor_ArraySubscriptExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003709 return cxstring::createRef("ArraySubscriptExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003710 case CXCursor_BinaryOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003711 return cxstring::createRef("BinaryOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003712 case CXCursor_CompoundAssignOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003713 return cxstring::createRef("CompoundAssignOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003714 case CXCursor_ConditionalOperator:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003715 return cxstring::createRef("ConditionalOperator");
Guy Benyei11169dd2012-12-18 14:30:41 +00003716 case CXCursor_CStyleCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003717 return cxstring::createRef("CStyleCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003718 case CXCursor_CompoundLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003719 return cxstring::createRef("CompoundLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003720 case CXCursor_InitListExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003721 return cxstring::createRef("InitListExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003722 case CXCursor_AddrLabelExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003723 return cxstring::createRef("AddrLabelExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003724 case CXCursor_StmtExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003725 return cxstring::createRef("StmtExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003726 case CXCursor_GenericSelectionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003727 return cxstring::createRef("GenericSelectionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003728 case CXCursor_GNUNullExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003729 return cxstring::createRef("GNUNullExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003730 case CXCursor_CXXStaticCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003731 return cxstring::createRef("CXXStaticCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003732 case CXCursor_CXXDynamicCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003733 return cxstring::createRef("CXXDynamicCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003734 case CXCursor_CXXReinterpretCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003735 return cxstring::createRef("CXXReinterpretCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003736 case CXCursor_CXXConstCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003737 return cxstring::createRef("CXXConstCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003738 case CXCursor_CXXFunctionalCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003739 return cxstring::createRef("CXXFunctionalCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003740 case CXCursor_CXXTypeidExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003741 return cxstring::createRef("CXXTypeidExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003742 case CXCursor_CXXBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003743 return cxstring::createRef("CXXBoolLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003744 case CXCursor_CXXNullPtrLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003745 return cxstring::createRef("CXXNullPtrLiteralExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003746 case CXCursor_CXXThisExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003747 return cxstring::createRef("CXXThisExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003748 case CXCursor_CXXThrowExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003749 return cxstring::createRef("CXXThrowExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003750 case CXCursor_CXXNewExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003751 return cxstring::createRef("CXXNewExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003752 case CXCursor_CXXDeleteExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003753 return cxstring::createRef("CXXDeleteExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003754 case CXCursor_UnaryExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003755 return cxstring::createRef("UnaryExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003756 case CXCursor_ObjCStringLiteral:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003757 return cxstring::createRef("ObjCStringLiteral");
Guy Benyei11169dd2012-12-18 14:30:41 +00003758 case CXCursor_ObjCBoolLiteralExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003759 return cxstring::createRef("ObjCBoolLiteralExpr");
Argyrios Kyrtzidisc2233be2013-04-23 17:57:17 +00003760 case CXCursor_ObjCSelfExpr:
3761 return cxstring::createRef("ObjCSelfExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003762 case CXCursor_ObjCEncodeExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003763 return cxstring::createRef("ObjCEncodeExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003764 case CXCursor_ObjCSelectorExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003765 return cxstring::createRef("ObjCSelectorExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003766 case CXCursor_ObjCProtocolExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003767 return cxstring::createRef("ObjCProtocolExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003768 case CXCursor_ObjCBridgedCastExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003769 return cxstring::createRef("ObjCBridgedCastExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003770 case CXCursor_BlockExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003771 return cxstring::createRef("BlockExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003772 case CXCursor_PackExpansionExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003773 return cxstring::createRef("PackExpansionExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003774 case CXCursor_SizeOfPackExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003775 return cxstring::createRef("SizeOfPackExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003776 case CXCursor_LambdaExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003777 return cxstring::createRef("LambdaExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003778 case CXCursor_UnexposedExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003779 return cxstring::createRef("UnexposedExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003780 case CXCursor_DeclRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003781 return cxstring::createRef("DeclRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003782 case CXCursor_MemberRefExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003783 return cxstring::createRef("MemberRefExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003784 case CXCursor_CallExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003785 return cxstring::createRef("CallExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003786 case CXCursor_ObjCMessageExpr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003787 return cxstring::createRef("ObjCMessageExpr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003788 case CXCursor_UnexposedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003789 return cxstring::createRef("UnexposedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003790 case CXCursor_DeclStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003791 return cxstring::createRef("DeclStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003792 case CXCursor_LabelStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003793 return cxstring::createRef("LabelStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003794 case CXCursor_CompoundStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003795 return cxstring::createRef("CompoundStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003796 case CXCursor_CaseStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003797 return cxstring::createRef("CaseStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003798 case CXCursor_DefaultStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003799 return cxstring::createRef("DefaultStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003800 case CXCursor_IfStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003801 return cxstring::createRef("IfStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003802 case CXCursor_SwitchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003803 return cxstring::createRef("SwitchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003804 case CXCursor_WhileStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003805 return cxstring::createRef("WhileStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003806 case CXCursor_DoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003807 return cxstring::createRef("DoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003808 case CXCursor_ForStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003809 return cxstring::createRef("ForStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003810 case CXCursor_GotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003811 return cxstring::createRef("GotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003812 case CXCursor_IndirectGotoStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003813 return cxstring::createRef("IndirectGotoStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003814 case CXCursor_ContinueStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003815 return cxstring::createRef("ContinueStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003816 case CXCursor_BreakStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003817 return cxstring::createRef("BreakStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003818 case CXCursor_ReturnStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003819 return cxstring::createRef("ReturnStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003820 case CXCursor_GCCAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003821 return cxstring::createRef("GCCAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003822 case CXCursor_MSAsmStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003823 return cxstring::createRef("MSAsmStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003824 case CXCursor_ObjCAtTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003825 return cxstring::createRef("ObjCAtTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003826 case CXCursor_ObjCAtCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003827 return cxstring::createRef("ObjCAtCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003828 case CXCursor_ObjCAtFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003829 return cxstring::createRef("ObjCAtFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003830 case CXCursor_ObjCAtThrowStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003831 return cxstring::createRef("ObjCAtThrowStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003832 case CXCursor_ObjCAtSynchronizedStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003833 return cxstring::createRef("ObjCAtSynchronizedStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003834 case CXCursor_ObjCAutoreleasePoolStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003835 return cxstring::createRef("ObjCAutoreleasePoolStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003836 case CXCursor_ObjCForCollectionStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003837 return cxstring::createRef("ObjCForCollectionStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003838 case CXCursor_CXXCatchStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003839 return cxstring::createRef("CXXCatchStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003840 case CXCursor_CXXTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003841 return cxstring::createRef("CXXTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003842 case CXCursor_CXXForRangeStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003843 return cxstring::createRef("CXXForRangeStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003844 case CXCursor_SEHTryStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003845 return cxstring::createRef("SEHTryStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003846 case CXCursor_SEHExceptStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003847 return cxstring::createRef("SEHExceptStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003848 case CXCursor_SEHFinallyStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003849 return cxstring::createRef("SEHFinallyStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003850 case CXCursor_NullStmt:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003851 return cxstring::createRef("NullStmt");
Guy Benyei11169dd2012-12-18 14:30:41 +00003852 case CXCursor_InvalidFile:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003853 return cxstring::createRef("InvalidFile");
Guy Benyei11169dd2012-12-18 14:30:41 +00003854 case CXCursor_InvalidCode:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003855 return cxstring::createRef("InvalidCode");
Guy Benyei11169dd2012-12-18 14:30:41 +00003856 case CXCursor_NoDeclFound:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003857 return cxstring::createRef("NoDeclFound");
Guy Benyei11169dd2012-12-18 14:30:41 +00003858 case CXCursor_NotImplemented:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003859 return cxstring::createRef("NotImplemented");
Guy Benyei11169dd2012-12-18 14:30:41 +00003860 case CXCursor_TranslationUnit:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003861 return cxstring::createRef("TranslationUnit");
Guy Benyei11169dd2012-12-18 14:30:41 +00003862 case CXCursor_UnexposedAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003863 return cxstring::createRef("UnexposedAttr");
Guy Benyei11169dd2012-12-18 14:30:41 +00003864 case CXCursor_IBActionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003865 return cxstring::createRef("attribute(ibaction)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003866 case CXCursor_IBOutletAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003867 return cxstring::createRef("attribute(iboutlet)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003868 case CXCursor_IBOutletCollectionAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003869 return cxstring::createRef("attribute(iboutletcollection)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003870 case CXCursor_CXXFinalAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003871 return cxstring::createRef("attribute(final)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003872 case CXCursor_CXXOverrideAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003873 return cxstring::createRef("attribute(override)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003874 case CXCursor_AnnotateAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003875 return cxstring::createRef("attribute(annotate)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003876 case CXCursor_AsmLabelAttr:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003877 return cxstring::createRef("asm label");
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00003878 case CXCursor_PackedAttr:
3879 return cxstring::createRef("attribute(packed)");
Joey Gouly81228382014-05-01 15:41:58 +00003880 case CXCursor_PureAttr:
3881 return cxstring::createRef("attribute(pure)");
3882 case CXCursor_ConstAttr:
3883 return cxstring::createRef("attribute(const)");
3884 case CXCursor_NoDuplicateAttr:
3885 return cxstring::createRef("attribute(noduplicate)");
Eli Bendersky2581e662014-05-28 19:29:58 +00003886 case CXCursor_CUDAConstantAttr:
3887 return cxstring::createRef("attribute(constant)");
3888 case CXCursor_CUDADeviceAttr:
3889 return cxstring::createRef("attribute(device)");
3890 case CXCursor_CUDAGlobalAttr:
3891 return cxstring::createRef("attribute(global)");
3892 case CXCursor_CUDAHostAttr:
3893 return cxstring::createRef("attribute(host)");
Guy Benyei11169dd2012-12-18 14:30:41 +00003894 case CXCursor_PreprocessingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003895 return cxstring::createRef("preprocessing directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003896 case CXCursor_MacroDefinition:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003897 return cxstring::createRef("macro definition");
Guy Benyei11169dd2012-12-18 14:30:41 +00003898 case CXCursor_MacroExpansion:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003899 return cxstring::createRef("macro expansion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003900 case CXCursor_InclusionDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003901 return cxstring::createRef("inclusion directive");
Guy Benyei11169dd2012-12-18 14:30:41 +00003902 case CXCursor_Namespace:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003903 return cxstring::createRef("Namespace");
Guy Benyei11169dd2012-12-18 14:30:41 +00003904 case CXCursor_LinkageSpec:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003905 return cxstring::createRef("LinkageSpec");
Guy Benyei11169dd2012-12-18 14:30:41 +00003906 case CXCursor_CXXBaseSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003907 return cxstring::createRef("C++ base class specifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003908 case CXCursor_Constructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003909 return cxstring::createRef("CXXConstructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003910 case CXCursor_Destructor:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003911 return cxstring::createRef("CXXDestructor");
Guy Benyei11169dd2012-12-18 14:30:41 +00003912 case CXCursor_ConversionFunction:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003913 return cxstring::createRef("CXXConversion");
Guy Benyei11169dd2012-12-18 14:30:41 +00003914 case CXCursor_TemplateTypeParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003915 return cxstring::createRef("TemplateTypeParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003916 case CXCursor_NonTypeTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003917 return cxstring::createRef("NonTypeTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003918 case CXCursor_TemplateTemplateParameter:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003919 return cxstring::createRef("TemplateTemplateParameter");
Guy Benyei11169dd2012-12-18 14:30:41 +00003920 case CXCursor_FunctionTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003921 return cxstring::createRef("FunctionTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003922 case CXCursor_ClassTemplate:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003923 return cxstring::createRef("ClassTemplate");
Guy Benyei11169dd2012-12-18 14:30:41 +00003924 case CXCursor_ClassTemplatePartialSpecialization:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003925 return cxstring::createRef("ClassTemplatePartialSpecialization");
Guy Benyei11169dd2012-12-18 14:30:41 +00003926 case CXCursor_NamespaceAlias:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003927 return cxstring::createRef("NamespaceAlias");
Guy Benyei11169dd2012-12-18 14:30:41 +00003928 case CXCursor_UsingDirective:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003929 return cxstring::createRef("UsingDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003930 case CXCursor_UsingDeclaration:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003931 return cxstring::createRef("UsingDeclaration");
Guy Benyei11169dd2012-12-18 14:30:41 +00003932 case CXCursor_TypeAliasDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003933 return cxstring::createRef("TypeAliasDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003934 case CXCursor_ObjCSynthesizeDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003935 return cxstring::createRef("ObjCSynthesizeDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003936 case CXCursor_ObjCDynamicDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003937 return cxstring::createRef("ObjCDynamicDecl");
Guy Benyei11169dd2012-12-18 14:30:41 +00003938 case CXCursor_CXXAccessSpecifier:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003939 return cxstring::createRef("CXXAccessSpecifier");
Guy Benyei11169dd2012-12-18 14:30:41 +00003940 case CXCursor_ModuleImportDecl:
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00003941 return cxstring::createRef("ModuleImport");
Alexey Bataev5ec3eb12013-07-19 03:13:43 +00003942 case CXCursor_OMPParallelDirective:
Alexey Bataev1b59ab52014-02-27 08:29:12 +00003943 return cxstring::createRef("OMPParallelDirective");
3944 case CXCursor_OMPSimdDirective:
3945 return cxstring::createRef("OMPSimdDirective");
Guy Benyei11169dd2012-12-18 14:30:41 +00003946 }
3947
3948 llvm_unreachable("Unhandled CXCursorKind");
3949}
3950
3951struct GetCursorData {
3952 SourceLocation TokenBeginLoc;
3953 bool PointsAtMacroArgExpansion;
3954 bool VisitedObjCPropertyImplDecl;
3955 SourceLocation VisitedDeclaratorDeclStartLoc;
3956 CXCursor &BestCursor;
3957
3958 GetCursorData(SourceManager &SM,
3959 SourceLocation tokenBegin, CXCursor &outputCursor)
3960 : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
3961 PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
3962 VisitedObjCPropertyImplDecl = false;
3963 }
3964};
3965
3966static enum CXChildVisitResult GetCursorVisitor(CXCursor cursor,
3967 CXCursor parent,
3968 CXClientData client_data) {
3969 GetCursorData *Data = static_cast<GetCursorData *>(client_data);
3970 CXCursor *BestCursor = &Data->BestCursor;
3971
3972 // If we point inside a macro argument we should provide info of what the
3973 // token is so use the actual cursor, don't replace it with a macro expansion
3974 // cursor.
3975 if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
3976 return CXChildVisit_Recurse;
3977
3978 if (clang_isDeclaration(cursor.kind)) {
3979 // Avoid having the implicit methods override the property decls.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003980 if (const ObjCMethodDecl *MD
Guy Benyei11169dd2012-12-18 14:30:41 +00003981 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
3982 if (MD->isImplicit())
3983 return CXChildVisit_Break;
3984
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003985 } else if (const ObjCInterfaceDecl *ID
Guy Benyei11169dd2012-12-18 14:30:41 +00003986 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
3987 // Check that when we have multiple @class references in the same line,
3988 // that later ones do not override the previous ones.
3989 // If we have:
3990 // @class Foo, Bar;
3991 // source ranges for both start at '@', so 'Bar' will end up overriding
3992 // 'Foo' even though the cursor location was at 'Foo'.
3993 if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
3994 BestCursor->kind == CXCursor_ObjCClassRef)
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00003995 if (const ObjCInterfaceDecl *PrevID
Guy Benyei11169dd2012-12-18 14:30:41 +00003996 = dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(*BestCursor))){
3997 if (PrevID != ID &&
3998 !PrevID->isThisDeclarationADefinition() &&
3999 !ID->isThisDeclarationADefinition())
4000 return CXChildVisit_Break;
4001 }
4002
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004003 } else if (const DeclaratorDecl *DD
Guy Benyei11169dd2012-12-18 14:30:41 +00004004 = dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
4005 SourceLocation StartLoc = DD->getSourceRange().getBegin();
4006 // Check that when we have multiple declarators in the same line,
4007 // that later ones do not override the previous ones.
4008 // If we have:
4009 // int Foo, Bar;
4010 // source ranges for both start at 'int', so 'Bar' will end up overriding
4011 // 'Foo' even though the cursor location was at 'Foo'.
4012 if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
4013 return CXChildVisit_Break;
4014 Data->VisitedDeclaratorDeclStartLoc = StartLoc;
4015
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004016 } else if (const ObjCPropertyImplDecl *PropImp
Guy Benyei11169dd2012-12-18 14:30:41 +00004017 = dyn_cast_or_null<ObjCPropertyImplDecl>(getCursorDecl(cursor))) {
4018 (void)PropImp;
4019 // Check that when we have multiple @synthesize in the same line,
4020 // that later ones do not override the previous ones.
4021 // If we have:
4022 // @synthesize Foo, Bar;
4023 // source ranges for both start at '@', so 'Bar' will end up overriding
4024 // 'Foo' even though the cursor location was at 'Foo'.
4025 if (Data->VisitedObjCPropertyImplDecl)
4026 return CXChildVisit_Break;
4027 Data->VisitedObjCPropertyImplDecl = true;
4028 }
4029 }
4030
4031 if (clang_isExpression(cursor.kind) &&
4032 clang_isDeclaration(BestCursor->kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004033 if (const Decl *D = getCursorDecl(*BestCursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004034 // Avoid having the cursor of an expression replace the declaration cursor
4035 // when the expression source range overlaps the declaration range.
4036 // This can happen for C++ constructor expressions whose range generally
4037 // include the variable declaration, e.g.:
4038 // MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl cursor.
4039 if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
4040 D->getLocation() == Data->TokenBeginLoc)
4041 return CXChildVisit_Break;
4042 }
4043 }
4044
4045 // If our current best cursor is the construction of a temporary object,
4046 // don't replace that cursor with a type reference, because we want
4047 // clang_getCursor() to point at the constructor.
4048 if (clang_isExpression(BestCursor->kind) &&
4049 isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
4050 cursor.kind == CXCursor_TypeRef) {
4051 // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
4052 // as having the actual point on the type reference.
4053 *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
4054 return CXChildVisit_Recurse;
4055 }
4056
4057 *BestCursor = cursor;
4058 return CXChildVisit_Recurse;
4059}
4060
4061CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00004062 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004063 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004064 return clang_getNullCursor();
Dmitri Gribenko256454f2014-02-11 14:34:14 +00004065 }
Guy Benyei11169dd2012-12-18 14:30:41 +00004066
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004067 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004068 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
4069
4070 SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
4071 CXCursor Result = cxcursor::getCursor(TU, SLoc);
4072
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004073 LOG_FUNC_SECTION {
Guy Benyei11169dd2012-12-18 14:30:41 +00004074 CXFile SearchFile;
4075 unsigned SearchLine, SearchColumn;
4076 CXFile ResultFile;
4077 unsigned ResultLine, ResultColumn;
4078 CXString SearchFileName, ResultFileName, KindSpelling, USR;
4079 const char *IsDef = clang_isCursorDefinition(Result)? " (Definition)" : "";
4080 CXSourceLocation ResultLoc = clang_getCursorLocation(Result);
4081
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004082 clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn, 0);
4083 clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine,
Guy Benyei11169dd2012-12-18 14:30:41 +00004084 &ResultColumn, 0);
4085 SearchFileName = clang_getFileName(SearchFile);
4086 ResultFileName = clang_getFileName(ResultFile);
4087 KindSpelling = clang_getCursorKindSpelling(Result.kind);
4088 USR = clang_getCursorUSR(Result);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004089 *Log << llvm::format("(%s:%d:%d) = %s",
4090 clang_getCString(SearchFileName), SearchLine, SearchColumn,
4091 clang_getCString(KindSpelling))
4092 << llvm::format("(%s:%d:%d):%s%s",
4093 clang_getCString(ResultFileName), ResultLine, ResultColumn,
4094 clang_getCString(USR), IsDef);
Guy Benyei11169dd2012-12-18 14:30:41 +00004095 clang_disposeString(SearchFileName);
4096 clang_disposeString(ResultFileName);
4097 clang_disposeString(KindSpelling);
4098 clang_disposeString(USR);
4099
4100 CXCursor Definition = clang_getCursorDefinition(Result);
4101 if (!clang_equalCursors(Definition, clang_getNullCursor())) {
4102 CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
4103 CXString DefinitionKindSpelling
4104 = clang_getCursorKindSpelling(Definition.kind);
4105 CXFile DefinitionFile;
4106 unsigned DefinitionLine, DefinitionColumn;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004107 clang_getFileLocation(DefinitionLoc, &DefinitionFile,
Guy Benyei11169dd2012-12-18 14:30:41 +00004108 &DefinitionLine, &DefinitionColumn, 0);
4109 CXString DefinitionFileName = clang_getFileName(DefinitionFile);
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00004110 *Log << llvm::format(" -> %s(%s:%d:%d)",
4111 clang_getCString(DefinitionKindSpelling),
4112 clang_getCString(DefinitionFileName),
4113 DefinitionLine, DefinitionColumn);
Guy Benyei11169dd2012-12-18 14:30:41 +00004114 clang_disposeString(DefinitionFileName);
4115 clang_disposeString(DefinitionKindSpelling);
4116 }
4117 }
4118
4119 return Result;
4120}
4121
4122CXCursor clang_getNullCursor(void) {
4123 return MakeCXCursorInvalid(CXCursor_InvalidFile);
4124}
4125
4126unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
Argyrios Kyrtzidisbf1be592013-01-08 18:23:28 +00004127 // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
4128 // can't set consistently. For example, when visiting a DeclStmt we will set
4129 // it but we don't set it on the result of clang_getCursorDefinition for
4130 // a reference of the same declaration.
4131 // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
4132 // when visiting a DeclStmt currently, the AST should be enhanced to be able
4133 // to provide that kind of info.
4134 if (clang_isDeclaration(X.kind))
4135 X.data[1] = 0;
4136 if (clang_isDeclaration(Y.kind))
4137 Y.data[1] = 0;
4138
Guy Benyei11169dd2012-12-18 14:30:41 +00004139 return X == Y;
4140}
4141
4142unsigned clang_hashCursor(CXCursor C) {
4143 unsigned Index = 0;
4144 if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
4145 Index = 1;
4146
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004147 return llvm::DenseMapInfo<std::pair<unsigned, const void*> >::getHashValue(
Guy Benyei11169dd2012-12-18 14:30:41 +00004148 std::make_pair(C.kind, C.data[Index]));
4149}
4150
4151unsigned clang_isInvalid(enum CXCursorKind K) {
4152 return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
4153}
4154
4155unsigned clang_isDeclaration(enum CXCursorKind K) {
4156 return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
4157 (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
4158}
4159
4160unsigned clang_isReference(enum CXCursorKind K) {
4161 return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
4162}
4163
4164unsigned clang_isExpression(enum CXCursorKind K) {
4165 return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
4166}
4167
4168unsigned clang_isStatement(enum CXCursorKind K) {
4169 return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
4170}
4171
4172unsigned clang_isAttribute(enum CXCursorKind K) {
4173 return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
4174}
4175
4176unsigned clang_isTranslationUnit(enum CXCursorKind K) {
4177 return K == CXCursor_TranslationUnit;
4178}
4179
4180unsigned clang_isPreprocessing(enum CXCursorKind K) {
4181 return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
4182}
4183
4184unsigned clang_isUnexposed(enum CXCursorKind K) {
4185 switch (K) {
4186 case CXCursor_UnexposedDecl:
4187 case CXCursor_UnexposedExpr:
4188 case CXCursor_UnexposedStmt:
4189 case CXCursor_UnexposedAttr:
4190 return true;
4191 default:
4192 return false;
4193 }
4194}
4195
4196CXCursorKind clang_getCursorKind(CXCursor C) {
4197 return C.kind;
4198}
4199
4200CXSourceLocation clang_getCursorLocation(CXCursor C) {
4201 if (clang_isReference(C.kind)) {
4202 switch (C.kind) {
4203 case CXCursor_ObjCSuperClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004204 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004205 = getCursorObjCSuperClassRef(C);
4206 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4207 }
4208
4209 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004210 std::pair<const ObjCProtocolDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004211 = getCursorObjCProtocolRef(C);
4212 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4213 }
4214
4215 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004216 std::pair<const ObjCInterfaceDecl *, SourceLocation> P
Guy Benyei11169dd2012-12-18 14:30:41 +00004217 = getCursorObjCClassRef(C);
4218 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4219 }
4220
4221 case CXCursor_TypeRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004222 std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004223 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4224 }
4225
4226 case CXCursor_TemplateRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004227 std::pair<const TemplateDecl *, SourceLocation> P =
4228 getCursorTemplateRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004229 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4230 }
4231
4232 case CXCursor_NamespaceRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004233 std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004234 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4235 }
4236
4237 case CXCursor_MemberRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004238 std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004239 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4240 }
4241
4242 case CXCursor_VariableRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004243 std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004244 return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
4245 }
4246
4247 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004248 const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004249 if (!BaseSpec)
4250 return clang_getNullLocation();
4251
4252 if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
4253 return cxloc::translateSourceLocation(getCursorContext(C),
4254 TSInfo->getTypeLoc().getBeginLoc());
4255
4256 return cxloc::translateSourceLocation(getCursorContext(C),
4257 BaseSpec->getLocStart());
4258 }
4259
4260 case CXCursor_LabelRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004261 std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004262 return cxloc::translateSourceLocation(getCursorContext(C), P.second);
4263 }
4264
4265 case CXCursor_OverloadedDeclRef:
4266 return cxloc::translateSourceLocation(getCursorContext(C),
4267 getCursorOverloadedDeclRef(C).second);
4268
4269 default:
4270 // FIXME: Need a way to enumerate all non-reference cases.
4271 llvm_unreachable("Missed a reference kind");
4272 }
4273 }
4274
4275 if (clang_isExpression(C.kind))
4276 return cxloc::translateSourceLocation(getCursorContext(C),
4277 getLocationFromExpr(getCursorExpr(C)));
4278
4279 if (clang_isStatement(C.kind))
4280 return cxloc::translateSourceLocation(getCursorContext(C),
4281 getCursorStmt(C)->getLocStart());
4282
4283 if (C.kind == CXCursor_PreprocessingDirective) {
4284 SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
4285 return cxloc::translateSourceLocation(getCursorContext(C), L);
4286 }
4287
4288 if (C.kind == CXCursor_MacroExpansion) {
4289 SourceLocation L
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004290 = cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
Guy Benyei11169dd2012-12-18 14:30:41 +00004291 return cxloc::translateSourceLocation(getCursorContext(C), L);
4292 }
4293
4294 if (C.kind == CXCursor_MacroDefinition) {
4295 SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
4296 return cxloc::translateSourceLocation(getCursorContext(C), L);
4297 }
4298
4299 if (C.kind == CXCursor_InclusionDirective) {
4300 SourceLocation L
4301 = cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
4302 return cxloc::translateSourceLocation(getCursorContext(C), L);
4303 }
4304
Argyrios Kyrtzidis16834f12013-09-25 00:14:38 +00004305 if (clang_isAttribute(C.kind)) {
4306 SourceLocation L
4307 = cxcursor::getCursorAttr(C)->getLocation();
4308 return cxloc::translateSourceLocation(getCursorContext(C), L);
4309 }
4310
Guy Benyei11169dd2012-12-18 14:30:41 +00004311 if (!clang_isDeclaration(C.kind))
4312 return clang_getNullLocation();
4313
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004314 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004315 if (!D)
4316 return clang_getNullLocation();
4317
4318 SourceLocation Loc = D->getLocation();
4319 // FIXME: Multiple variables declared in a single declaration
4320 // currently lack the information needed to correctly determine their
4321 // ranges when accounting for the type-specifier. We use context
4322 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4323 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004324 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004325 if (!cxcursor::isFirstInDeclGroup(C))
4326 Loc = VD->getLocation();
4327 }
4328
4329 // For ObjC methods, give the start location of the method name.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004330 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004331 Loc = MD->getSelectorStartLoc();
4332
4333 return cxloc::translateSourceLocation(getCursorContext(C), Loc);
4334}
4335
4336} // end extern "C"
4337
4338CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
4339 assert(TU);
4340
4341 // Guard against an invalid SourceLocation, or we may assert in one
4342 // of the following calls.
4343 if (SLoc.isInvalid())
4344 return clang_getNullCursor();
4345
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004346 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004347
4348 // Translate the given source location to make it point at the beginning of
4349 // the token under the cursor.
4350 SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
4351 CXXUnit->getASTContext().getLangOpts());
4352
4353 CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
4354 if (SLoc.isValid()) {
4355 GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
4356 CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
4357 /*VisitPreprocessorLast=*/true,
4358 /*VisitIncludedEntities=*/false,
4359 SourceLocation(SLoc));
4360 CursorVis.visitFileRegion();
4361 }
4362
4363 return Result;
4364}
4365
4366static SourceRange getRawCursorExtent(CXCursor C) {
4367 if (clang_isReference(C.kind)) {
4368 switch (C.kind) {
4369 case CXCursor_ObjCSuperClassRef:
4370 return getCursorObjCSuperClassRef(C).second;
4371
4372 case CXCursor_ObjCProtocolRef:
4373 return getCursorObjCProtocolRef(C).second;
4374
4375 case CXCursor_ObjCClassRef:
4376 return getCursorObjCClassRef(C).second;
4377
4378 case CXCursor_TypeRef:
4379 return getCursorTypeRef(C).second;
4380
4381 case CXCursor_TemplateRef:
4382 return getCursorTemplateRef(C).second;
4383
4384 case CXCursor_NamespaceRef:
4385 return getCursorNamespaceRef(C).second;
4386
4387 case CXCursor_MemberRef:
4388 return getCursorMemberRef(C).second;
4389
4390 case CXCursor_CXXBaseSpecifier:
4391 return getCursorCXXBaseSpecifier(C)->getSourceRange();
4392
4393 case CXCursor_LabelRef:
4394 return getCursorLabelRef(C).second;
4395
4396 case CXCursor_OverloadedDeclRef:
4397 return getCursorOverloadedDeclRef(C).second;
4398
4399 case CXCursor_VariableRef:
4400 return getCursorVariableRef(C).second;
4401
4402 default:
4403 // FIXME: Need a way to enumerate all non-reference cases.
4404 llvm_unreachable("Missed a reference kind");
4405 }
4406 }
4407
4408 if (clang_isExpression(C.kind))
4409 return getCursorExpr(C)->getSourceRange();
4410
4411 if (clang_isStatement(C.kind))
4412 return getCursorStmt(C)->getSourceRange();
4413
4414 if (clang_isAttribute(C.kind))
4415 return getCursorAttr(C)->getRange();
4416
4417 if (C.kind == CXCursor_PreprocessingDirective)
4418 return cxcursor::getCursorPreprocessingDirective(C);
4419
4420 if (C.kind == CXCursor_MacroExpansion) {
4421 ASTUnit *TU = getCursorASTUnit(C);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00004422 SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00004423 return TU->mapRangeFromPreamble(Range);
4424 }
4425
4426 if (C.kind == CXCursor_MacroDefinition) {
4427 ASTUnit *TU = getCursorASTUnit(C);
4428 SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
4429 return TU->mapRangeFromPreamble(Range);
4430 }
4431
4432 if (C.kind == CXCursor_InclusionDirective) {
4433 ASTUnit *TU = getCursorASTUnit(C);
4434 SourceRange Range = cxcursor::getCursorInclusionDirective(C)->getSourceRange();
4435 return TU->mapRangeFromPreamble(Range);
4436 }
4437
4438 if (C.kind == CXCursor_TranslationUnit) {
4439 ASTUnit *TU = getCursorASTUnit(C);
4440 FileID MainID = TU->getSourceManager().getMainFileID();
4441 SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
4442 SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
4443 return SourceRange(Start, End);
4444 }
4445
4446 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004447 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004448 if (!D)
4449 return SourceRange();
4450
4451 SourceRange R = D->getSourceRange();
4452 // FIXME: Multiple variables declared in a single declaration
4453 // currently lack the information needed to correctly determine their
4454 // ranges when accounting for the type-specifier. We use context
4455 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4456 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004457 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004458 if (!cxcursor::isFirstInDeclGroup(C))
4459 R.setBegin(VD->getLocation());
4460 }
4461 return R;
4462 }
4463 return SourceRange();
4464}
4465
4466/// \brief Retrieves the "raw" cursor extent, which is then extended to include
4467/// the decl-specifier-seq for declarations.
4468static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
4469 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004470 const Decl *D = cxcursor::getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004471 if (!D)
4472 return SourceRange();
4473
4474 SourceRange R = D->getSourceRange();
4475
4476 // Adjust the start of the location for declarations preceded by
4477 // declaration specifiers.
4478 SourceLocation StartLoc;
4479 if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
4480 if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
4481 StartLoc = TI->getTypeLoc().getLocStart();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004482 } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004483 if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
4484 StartLoc = TI->getTypeLoc().getLocStart();
4485 }
4486
4487 if (StartLoc.isValid() && R.getBegin().isValid() &&
4488 SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
4489 R.setBegin(StartLoc);
4490
4491 // FIXME: Multiple variables declared in a single declaration
4492 // currently lack the information needed to correctly determine their
4493 // ranges when accounting for the type-specifier. We use context
4494 // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
4495 // and if so, whether it is the first decl.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004496 if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004497 if (!cxcursor::isFirstInDeclGroup(C))
4498 R.setBegin(VD->getLocation());
4499 }
4500
4501 return R;
4502 }
4503
4504 return getRawCursorExtent(C);
4505}
4506
4507extern "C" {
4508
4509CXSourceRange clang_getCursorExtent(CXCursor C) {
4510 SourceRange R = getRawCursorExtent(C);
4511 if (R.isInvalid())
4512 return clang_getNullRange();
4513
4514 return cxloc::translateSourceRange(getCursorContext(C), R);
4515}
4516
4517CXCursor clang_getCursorReferenced(CXCursor C) {
4518 if (clang_isInvalid(C.kind))
4519 return clang_getNullCursor();
4520
4521 CXTranslationUnit tu = getCursorTU(C);
4522 if (clang_isDeclaration(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004523 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004524 if (!D)
4525 return clang_getNullCursor();
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004526 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004527 return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004528 if (const ObjCPropertyImplDecl *PropImpl =
4529 dyn_cast<ObjCPropertyImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004530 if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
4531 return MakeCXCursor(Property, tu);
4532
4533 return C;
4534 }
4535
4536 if (clang_isExpression(C.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004537 const Expr *E = getCursorExpr(C);
4538 const Decl *D = getDeclFromExpr(E);
Guy Benyei11169dd2012-12-18 14:30:41 +00004539 if (D) {
4540 CXCursor declCursor = MakeCXCursor(D, tu);
4541 declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
4542 declCursor);
4543 return declCursor;
4544 }
4545
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004546 if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
Guy Benyei11169dd2012-12-18 14:30:41 +00004547 return MakeCursorOverloadedDeclRef(Ovl, tu);
4548
4549 return clang_getNullCursor();
4550 }
4551
4552 if (clang_isStatement(C.kind)) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004553 const Stmt *S = getCursorStmt(C);
4554 if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
Guy Benyei11169dd2012-12-18 14:30:41 +00004555 if (LabelDecl *label = Goto->getLabel())
4556 if (LabelStmt *labelS = label->getStmt())
4557 return MakeCXCursor(labelS, getCursorDecl(C), tu);
4558
4559 return clang_getNullCursor();
4560 }
4561
4562 if (C.kind == CXCursor_MacroExpansion) {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004563 if (const MacroDefinition *Def = getCursorMacroExpansion(C).getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004564 return MakeMacroDefinitionCursor(Def, tu);
4565 }
4566
4567 if (!clang_isReference(C.kind))
4568 return clang_getNullCursor();
4569
4570 switch (C.kind) {
4571 case CXCursor_ObjCSuperClassRef:
4572 return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);
4573
4574 case CXCursor_ObjCProtocolRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004575 const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
4576 if (const ObjCProtocolDecl *Def = Prot->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004577 return MakeCXCursor(Def, tu);
4578
4579 return MakeCXCursor(Prot, tu);
4580 }
4581
4582 case CXCursor_ObjCClassRef: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004583 const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
4584 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004585 return MakeCXCursor(Def, tu);
4586
4587 return MakeCXCursor(Class, tu);
4588 }
4589
4590 case CXCursor_TypeRef:
4591 return MakeCXCursor(getCursorTypeRef(C).first, tu );
4592
4593 case CXCursor_TemplateRef:
4594 return MakeCXCursor(getCursorTemplateRef(C).first, tu );
4595
4596 case CXCursor_NamespaceRef:
4597 return MakeCXCursor(getCursorNamespaceRef(C).first, tu );
4598
4599 case CXCursor_MemberRef:
4600 return MakeCXCursor(getCursorMemberRef(C).first, tu );
4601
4602 case CXCursor_CXXBaseSpecifier: {
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00004603 const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004604 return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(),
4605 tu ));
4606 }
4607
4608 case CXCursor_LabelRef:
4609 // FIXME: We end up faking the "parent" declaration here because we
4610 // don't want to make CXCursor larger.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00004611 return MakeCXCursor(getCursorLabelRef(C).first,
4612 cxtu::getASTUnit(tu)->getASTContext()
4613 .getTranslationUnitDecl(),
Guy Benyei11169dd2012-12-18 14:30:41 +00004614 tu);
4615
4616 case CXCursor_OverloadedDeclRef:
4617 return C;
4618
4619 case CXCursor_VariableRef:
4620 return MakeCXCursor(getCursorVariableRef(C).first, tu);
4621
4622 default:
4623 // We would prefer to enumerate all non-reference cursor kinds here.
4624 llvm_unreachable("Unhandled reference cursor kind");
4625 }
4626}
4627
4628CXCursor clang_getCursorDefinition(CXCursor C) {
4629 if (clang_isInvalid(C.kind))
4630 return clang_getNullCursor();
4631
4632 CXTranslationUnit TU = getCursorTU(C);
4633
4634 bool WasReference = false;
4635 if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
4636 C = clang_getCursorReferenced(C);
4637 WasReference = true;
4638 }
4639
4640 if (C.kind == CXCursor_MacroExpansion)
4641 return clang_getCursorReferenced(C);
4642
4643 if (!clang_isDeclaration(C.kind))
4644 return clang_getNullCursor();
4645
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004646 const Decl *D = getCursorDecl(C);
Guy Benyei11169dd2012-12-18 14:30:41 +00004647 if (!D)
4648 return clang_getNullCursor();
4649
4650 switch (D->getKind()) {
4651 // Declaration kinds that don't really separate the notions of
4652 // declaration and definition.
4653 case Decl::Namespace:
4654 case Decl::Typedef:
4655 case Decl::TypeAlias:
4656 case Decl::TypeAliasTemplate:
4657 case Decl::TemplateTypeParm:
4658 case Decl::EnumConstant:
4659 case Decl::Field:
John McCall5e77d762013-04-16 07:28:30 +00004660 case Decl::MSProperty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004661 case Decl::IndirectField:
4662 case Decl::ObjCIvar:
4663 case Decl::ObjCAtDefsField:
4664 case Decl::ImplicitParam:
4665 case Decl::ParmVar:
4666 case Decl::NonTypeTemplateParm:
4667 case Decl::TemplateTemplateParm:
4668 case Decl::ObjCCategoryImpl:
4669 case Decl::ObjCImplementation:
4670 case Decl::AccessSpec:
4671 case Decl::LinkageSpec:
4672 case Decl::ObjCPropertyImpl:
4673 case Decl::FileScopeAsm:
4674 case Decl::StaticAssert:
4675 case Decl::Block:
Tareq A. Siraj6dfa25a2013-04-16 19:37:38 +00004676 case Decl::Captured:
Guy Benyei11169dd2012-12-18 14:30:41 +00004677 case Decl::Label: // FIXME: Is this right??
4678 case Decl::ClassScopeFunctionSpecialization:
4679 case Decl::Import:
Alexey Bataeva769e072013-03-22 06:34:35 +00004680 case Decl::OMPThreadPrivate:
Guy Benyei11169dd2012-12-18 14:30:41 +00004681 return C;
4682
4683 // Declaration kinds that don't make any sense here, but are
4684 // nonetheless harmless.
David Blaikief005d3c2013-02-22 17:44:58 +00004685 case Decl::Empty:
Guy Benyei11169dd2012-12-18 14:30:41 +00004686 case Decl::TranslationUnit:
4687 break;
4688
4689 // Declaration kinds for which the definition is not resolvable.
4690 case Decl::UnresolvedUsingTypename:
4691 case Decl::UnresolvedUsingValue:
4692 break;
4693
4694 case Decl::UsingDirective:
4695 return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
4696 TU);
4697
4698 case Decl::NamespaceAlias:
4699 return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);
4700
4701 case Decl::Enum:
4702 case Decl::Record:
4703 case Decl::CXXRecord:
4704 case Decl::ClassTemplateSpecialization:
4705 case Decl::ClassTemplatePartialSpecialization:
4706 if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
4707 return MakeCXCursor(Def, TU);
4708 return clang_getNullCursor();
4709
4710 case Decl::Function:
4711 case Decl::CXXMethod:
4712 case Decl::CXXConstructor:
4713 case Decl::CXXDestructor:
4714 case Decl::CXXConversion: {
4715 const FunctionDecl *Def = 0;
4716 if (cast<FunctionDecl>(D)->getBody(Def))
Dmitri Gribenko9c256e32013-01-14 00:46:27 +00004717 return MakeCXCursor(Def, TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00004718 return clang_getNullCursor();
4719 }
4720
Larisse Voufo39a1e502013-08-06 01:03:05 +00004721 case Decl::Var:
4722 case Decl::VarTemplateSpecialization:
4723 case Decl::VarTemplatePartialSpecialization: {
Guy Benyei11169dd2012-12-18 14:30:41 +00004724 // Ask the variable if it has a definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004725 if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004726 return MakeCXCursor(Def, TU);
4727 return clang_getNullCursor();
4728 }
4729
4730 case Decl::FunctionTemplate: {
4731 const FunctionDecl *Def = 0;
4732 if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
4733 return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
4734 return clang_getNullCursor();
4735 }
4736
4737 case Decl::ClassTemplate: {
4738 if (RecordDecl *Def = cast<ClassTemplateDecl>(D)->getTemplatedDecl()
4739 ->getDefinition())
4740 return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
4741 TU);
4742 return clang_getNullCursor();
4743 }
4744
Larisse Voufo39a1e502013-08-06 01:03:05 +00004745 case Decl::VarTemplate: {
4746 if (VarDecl *Def =
4747 cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
4748 return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
4749 return clang_getNullCursor();
4750 }
4751
Guy Benyei11169dd2012-12-18 14:30:41 +00004752 case Decl::Using:
4753 return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D),
4754 D->getLocation(), TU);
4755
4756 case Decl::UsingShadow:
4757 return clang_getCursorDefinition(
4758 MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(),
4759 TU));
4760
4761 case Decl::ObjCMethod: {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004762 const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004763 if (Method->isThisDeclarationADefinition())
4764 return C;
4765
4766 // Dig out the method definition in the associated
4767 // @implementation, if we have it.
4768 // FIXME: The ASTs should make finding the definition easier.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004769 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004770 = dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
4771 if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
4772 if (ObjCMethodDecl *Def = ClassImpl->getMethod(Method->getSelector(),
4773 Method->isInstanceMethod()))
4774 if (Def->isThisDeclarationADefinition())
4775 return MakeCXCursor(Def, TU);
4776
4777 return clang_getNullCursor();
4778 }
4779
4780 case Decl::ObjCCategory:
4781 if (ObjCCategoryImplDecl *Impl
4782 = cast<ObjCCategoryDecl>(D)->getImplementation())
4783 return MakeCXCursor(Impl, TU);
4784 return clang_getNullCursor();
4785
4786 case Decl::ObjCProtocol:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004787 if (const ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(D)->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004788 return MakeCXCursor(Def, TU);
4789 return clang_getNullCursor();
4790
4791 case Decl::ObjCInterface: {
4792 // There are two notions of a "definition" for an Objective-C
4793 // class: the interface and its implementation. When we resolved a
4794 // reference to an Objective-C class, produce the @interface as
4795 // the definition; when we were provided with the interface,
4796 // produce the @implementation as the definition.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004797 const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00004798 if (WasReference) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004799 if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004800 return MakeCXCursor(Def, TU);
4801 } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
4802 return MakeCXCursor(Impl, TU);
4803 return clang_getNullCursor();
4804 }
4805
4806 case Decl::ObjCProperty:
4807 // FIXME: We don't really know where to find the
4808 // ObjCPropertyImplDecls that implement this property.
4809 return clang_getNullCursor();
4810
4811 case Decl::ObjCCompatibleAlias:
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004812 if (const ObjCInterfaceDecl *Class
Guy Benyei11169dd2012-12-18 14:30:41 +00004813 = cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004814 if (const ObjCInterfaceDecl *Def = Class->getDefinition())
Guy Benyei11169dd2012-12-18 14:30:41 +00004815 return MakeCXCursor(Def, TU);
4816
4817 return clang_getNullCursor();
4818
4819 case Decl::Friend:
4820 if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
4821 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4822 return clang_getNullCursor();
4823
4824 case Decl::FriendTemplate:
4825 if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
4826 return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
4827 return clang_getNullCursor();
4828 }
4829
4830 return clang_getNullCursor();
4831}
4832
4833unsigned clang_isCursorDefinition(CXCursor C) {
4834 if (!clang_isDeclaration(C.kind))
4835 return 0;
4836
4837 return clang_getCursorDefinition(C) == C;
4838}
4839
4840CXCursor clang_getCanonicalCursor(CXCursor C) {
4841 if (!clang_isDeclaration(C.kind))
4842 return C;
4843
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004844 if (const Decl *D = getCursorDecl(C)) {
4845 if (const ObjCCategoryImplDecl *CatImplD = dyn_cast<ObjCCategoryImplDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004846 if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
4847 return MakeCXCursor(CatD, getCursorTU(C));
4848
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004849 if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
4850 if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
Guy Benyei11169dd2012-12-18 14:30:41 +00004851 return MakeCXCursor(IFD, getCursorTU(C));
4852
4853 return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
4854 }
4855
4856 return C;
4857}
4858
4859int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
4860 return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
4861}
4862
4863unsigned clang_getNumOverloadedDecls(CXCursor C) {
4864 if (C.kind != CXCursor_OverloadedDeclRef)
4865 return 0;
4866
4867 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004868 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004869 return E->getNumDecls();
4870
4871 if (OverloadedTemplateStorage *S
4872 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4873 return S->size();
4874
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004875 const Decl *D = Storage.get<const Decl *>();
4876 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00004877 return Using->shadow_size();
4878
4879 return 0;
4880}
4881
4882CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
4883 if (cursor.kind != CXCursor_OverloadedDeclRef)
4884 return clang_getNullCursor();
4885
4886 if (index >= clang_getNumOverloadedDecls(cursor))
4887 return clang_getNullCursor();
4888
4889 CXTranslationUnit TU = getCursorTU(cursor);
4890 OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004891 if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
Guy Benyei11169dd2012-12-18 14:30:41 +00004892 return MakeCXCursor(E->decls_begin()[index], TU);
4893
4894 if (OverloadedTemplateStorage *S
4895 = Storage.dyn_cast<OverloadedTemplateStorage*>())
4896 return MakeCXCursor(S->begin()[index], TU);
4897
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004898 const Decl *D = Storage.get<const Decl *>();
4899 if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00004900 // FIXME: This is, unfortunately, linear time.
4901 UsingDecl::shadow_iterator Pos = Using->shadow_begin();
4902 std::advance(Pos, index);
4903 return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
4904 }
4905
4906 return clang_getNullCursor();
4907}
4908
4909void clang_getDefinitionSpellingAndExtent(CXCursor C,
4910 const char **startBuf,
4911 const char **endBuf,
4912 unsigned *startLine,
4913 unsigned *startColumn,
4914 unsigned *endLine,
4915 unsigned *endColumn) {
4916 assert(getCursorDecl(C) && "CXCursor has null decl");
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00004917 const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
Guy Benyei11169dd2012-12-18 14:30:41 +00004918 CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());
4919
4920 SourceManager &SM = FD->getASTContext().getSourceManager();
4921 *startBuf = SM.getCharacterData(Body->getLBracLoc());
4922 *endBuf = SM.getCharacterData(Body->getRBracLoc());
4923 *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
4924 *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
4925 *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
4926 *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
4927}
4928
4929
4930CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
4931 unsigned PieceIndex) {
4932 RefNamePieces Pieces;
4933
4934 switch (C.kind) {
4935 case CXCursor_MemberRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004936 if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004937 Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
4938 E->getQualifierLoc().getSourceRange());
4939 break;
4940
4941 case CXCursor_DeclRefExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004942 if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00004943 Pieces = buildPieces(NameFlags, false, E->getNameInfo(),
4944 E->getQualifierLoc().getSourceRange(),
4945 E->getOptionalExplicitTemplateArgs());
4946 break;
4947
4948 case CXCursor_CallExpr:
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004949 if (const CXXOperatorCallExpr *OCE =
Guy Benyei11169dd2012-12-18 14:30:41 +00004950 dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004951 const Expr *Callee = OCE->getCallee();
4952 if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004953 Callee = ICE->getSubExpr();
4954
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00004955 if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
Guy Benyei11169dd2012-12-18 14:30:41 +00004956 Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
4957 DRE->getQualifierLoc().getSourceRange());
4958 }
4959 break;
4960
4961 default:
4962 break;
4963 }
4964
4965 if (Pieces.empty()) {
4966 if (PieceIndex == 0)
4967 return clang_getCursorExtent(C);
4968 } else if (PieceIndex < Pieces.size()) {
4969 SourceRange R = Pieces[PieceIndex];
4970 if (R.isValid())
4971 return cxloc::translateSourceRange(getCursorContext(C), R);
4972 }
4973
4974 return clang_getNullRange();
4975}
4976
4977void clang_enableStackTraces(void) {
4978 llvm::sys::PrintStackTraceOnErrorSignal();
4979}
4980
4981void clang_executeOnThread(void (*fn)(void*), void *user_data,
4982 unsigned stack_size) {
4983 llvm::llvm_execute_on_thread(fn, user_data, stack_size);
4984}
4985
4986} // end: extern "C"
4987
4988//===----------------------------------------------------------------------===//
4989// Token-based Operations.
4990//===----------------------------------------------------------------------===//
4991
4992/* CXToken layout:
4993 * int_data[0]: a CXTokenKind
4994 * int_data[1]: starting token location
4995 * int_data[2]: token length
4996 * int_data[3]: reserved
4997 * ptr_data: for identifiers and keywords, an IdentifierInfo*.
4998 * otherwise unused.
4999 */
5000extern "C" {
5001
5002CXTokenKind clang_getTokenKind(CXToken CXTok) {
5003 return static_cast<CXTokenKind>(CXTok.int_data[0]);
5004}
5005
5006CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
5007 switch (clang_getTokenKind(CXTok)) {
5008 case CXToken_Identifier:
5009 case CXToken_Keyword:
5010 // We know we have an IdentifierInfo*, so use that.
Dmitri Gribenko3c66b0b2013-02-02 00:02:12 +00005011 return cxstring::createRef(static_cast<IdentifierInfo *>(CXTok.ptr_data)
Guy Benyei11169dd2012-12-18 14:30:41 +00005012 ->getNameStart());
5013
5014 case CXToken_Literal: {
5015 // We have stashed the starting pointer in the ptr_data field. Use it.
5016 const char *Text = static_cast<const char *>(CXTok.ptr_data);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005017 return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005018 }
5019
5020 case CXToken_Punctuation:
5021 case CXToken_Comment:
5022 break;
5023 }
5024
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 cxstring::createEmpty();
5028 }
5029
Guy Benyei11169dd2012-12-18 14:30:41 +00005030 // We have to find the starting buffer pointer the hard way, by
5031 // deconstructing the source location.
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005032 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005033 if (!CXXUnit)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005034 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005035
5036 SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
5037 std::pair<FileID, unsigned> LocInfo
5038 = CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
5039 bool Invalid = false;
5040 StringRef Buffer
5041 = CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
5042 if (Invalid)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00005043 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00005044
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00005045 return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005046}
5047
5048CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005049 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005050 LOG_BAD_TU(TU);
5051 return clang_getNullLocation();
5052 }
5053
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005054 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005055 if (!CXXUnit)
5056 return clang_getNullLocation();
5057
5058 return cxloc::translateSourceLocation(CXXUnit->getASTContext(),
5059 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5060}
5061
5062CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005063 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005064 LOG_BAD_TU(TU);
5065 return clang_getNullRange();
5066 }
5067
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005068 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005069 if (!CXXUnit)
5070 return clang_getNullRange();
5071
5072 return cxloc::translateSourceRange(CXXUnit->getASTContext(),
5073 SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
5074}
5075
5076static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
5077 SmallVectorImpl<CXToken> &CXTokens) {
5078 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5079 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005080 = SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005081 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005082 = SourceMgr.getDecomposedSpellingLoc(Range.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005083
5084 // Cannot tokenize across files.
5085 if (BeginLocInfo.first != EndLocInfo.first)
5086 return;
5087
5088 // Create a lexer
5089 bool Invalid = false;
5090 StringRef Buffer
5091 = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5092 if (Invalid)
5093 return;
5094
5095 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5096 CXXUnit->getASTContext().getLangOpts(),
5097 Buffer.begin(), Buffer.data() + BeginLocInfo.second, Buffer.end());
5098 Lex.SetCommentRetentionState(true);
5099
5100 // Lex tokens until we hit the end of the range.
5101 const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
5102 Token Tok;
5103 bool previousWasAt = false;
5104 do {
5105 // Lex the next token
5106 Lex.LexFromRawLexer(Tok);
5107 if (Tok.is(tok::eof))
5108 break;
5109
5110 // Initialize the CXToken.
5111 CXToken CXTok;
5112
5113 // - Common fields
5114 CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
5115 CXTok.int_data[2] = Tok.getLength();
5116 CXTok.int_data[3] = 0;
5117
5118 // - Kind-specific fields
5119 if (Tok.isLiteral()) {
5120 CXTok.int_data[0] = CXToken_Literal;
Dmitri Gribenkof9304482013-01-23 15:56:07 +00005121 CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
Guy Benyei11169dd2012-12-18 14:30:41 +00005122 } else if (Tok.is(tok::raw_identifier)) {
5123 // Lookup the identifier to determine whether we have a keyword.
5124 IdentifierInfo *II
5125 = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);
5126
5127 if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
5128 CXTok.int_data[0] = CXToken_Keyword;
5129 }
5130 else {
5131 CXTok.int_data[0] = Tok.is(tok::identifier)
5132 ? CXToken_Identifier
5133 : CXToken_Keyword;
5134 }
5135 CXTok.ptr_data = II;
5136 } else if (Tok.is(tok::comment)) {
5137 CXTok.int_data[0] = CXToken_Comment;
5138 CXTok.ptr_data = 0;
5139 } else {
5140 CXTok.int_data[0] = CXToken_Punctuation;
5141 CXTok.ptr_data = 0;
5142 }
5143 CXTokens.push_back(CXTok);
5144 previousWasAt = Tok.is(tok::at);
5145 } while (Lex.getBufferLocation() <= EffectiveBufferEnd);
5146}
5147
5148void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
5149 CXToken **Tokens, unsigned *NumTokens) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005150 LOG_FUNC_SECTION {
5151 *Log << TU << ' ' << Range;
5152 }
5153
Guy Benyei11169dd2012-12-18 14:30:41 +00005154 if (Tokens)
5155 *Tokens = 0;
5156 if (NumTokens)
5157 *NumTokens = 0;
5158
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005159 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005160 LOG_BAD_TU(TU);
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005161 return;
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005162 }
Argyrios Kyrtzidis0e95fca2013-04-04 22:40:59 +00005163
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005164 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005165 if (!CXXUnit || !Tokens || !NumTokens)
5166 return;
5167
5168 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5169
5170 SourceRange R = cxloc::translateCXSourceRange(Range);
5171 if (R.isInvalid())
5172 return;
5173
5174 SmallVector<CXToken, 32> CXTokens;
5175 getTokens(CXXUnit, R, CXTokens);
5176
5177 if (CXTokens.empty())
5178 return;
5179
5180 *Tokens = (CXToken *)malloc(sizeof(CXToken) * CXTokens.size());
5181 memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
5182 *NumTokens = CXTokens.size();
5183}
5184
5185void clang_disposeTokens(CXTranslationUnit TU,
5186 CXToken *Tokens, unsigned NumTokens) {
5187 free(Tokens);
5188}
5189
5190} // end: extern "C"
5191
5192//===----------------------------------------------------------------------===//
5193// Token annotation APIs.
5194//===----------------------------------------------------------------------===//
5195
Guy Benyei11169dd2012-12-18 14:30:41 +00005196static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5197 CXCursor parent,
5198 CXClientData client_data);
5199static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5200 CXClientData client_data);
5201
5202namespace {
5203class AnnotateTokensWorker {
Guy Benyei11169dd2012-12-18 14:30:41 +00005204 CXToken *Tokens;
5205 CXCursor *Cursors;
5206 unsigned NumTokens;
5207 unsigned TokIdx;
5208 unsigned PreprocessingTokIdx;
5209 CursorVisitor AnnotateVis;
5210 SourceManager &SrcMgr;
5211 bool HasContextSensitiveKeywords;
5212
5213 struct PostChildrenInfo {
5214 CXCursor Cursor;
5215 SourceRange CursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005216 unsigned BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005217 unsigned BeforeChildrenTokenIdx;
5218 };
Dmitri Gribenkof8579502013-01-12 19:30:44 +00005219 SmallVector<PostChildrenInfo, 8> PostChildrenInfos;
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005220
5221 CXToken &getTok(unsigned Idx) {
5222 assert(Idx < NumTokens);
5223 return Tokens[Idx];
5224 }
5225 const CXToken &getTok(unsigned Idx) const {
5226 assert(Idx < NumTokens);
5227 return Tokens[Idx];
5228 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005229 bool MoreTokens() const { return TokIdx < NumTokens; }
5230 unsigned NextToken() const { return TokIdx; }
5231 void AdvanceToken() { ++TokIdx; }
5232 SourceLocation GetTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005233 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005234 }
5235 bool isFunctionMacroToken(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005236 return getTok(tokI).int_data[3] != 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005237 }
5238 SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005239 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005240 }
5241
5242 void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005243 bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
Guy Benyei11169dd2012-12-18 14:30:41 +00005244 SourceRange);
5245
5246public:
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005247 AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005248 CXTranslationUnit TU, SourceRange RegionOfInterest)
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005249 : Tokens(tokens), Cursors(cursors),
Guy Benyei11169dd2012-12-18 14:30:41 +00005250 NumTokens(numTokens), TokIdx(0), PreprocessingTokIdx(0),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005251 AnnotateVis(TU,
Guy Benyei11169dd2012-12-18 14:30:41 +00005252 AnnotateTokensVisitor, this,
5253 /*VisitPreprocessorLast=*/true,
5254 /*VisitIncludedEntities=*/false,
5255 RegionOfInterest,
5256 /*VisitDeclsOnly=*/false,
5257 AnnotateTokensPostChildrenVisitor),
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005258 SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
Guy Benyei11169dd2012-12-18 14:30:41 +00005259 HasContextSensitiveKeywords(false) { }
5260
5261 void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
5262 enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
5263 bool postVisitChildren(CXCursor cursor);
5264 void AnnotateTokens();
5265
5266 /// \brief Determine whether the annotator saw any cursors that have
5267 /// context-sensitive keywords.
5268 bool hasContextSensitiveKeywords() const {
5269 return HasContextSensitiveKeywords;
5270 }
5271
5272 ~AnnotateTokensWorker() {
5273 assert(PostChildrenInfos.empty());
5274 }
5275};
5276}
5277
5278void AnnotateTokensWorker::AnnotateTokens() {
5279 // Walk the AST within the region of interest, annotating tokens
5280 // along the way.
5281 AnnotateVis.visitFileRegion();
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005282}
Guy Benyei11169dd2012-12-18 14:30:41 +00005283
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005284static inline void updateCursorAnnotation(CXCursor &Cursor,
5285 const CXCursor &updateC) {
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005286 if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005287 return;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005288 Cursor = updateC;
Guy Benyei11169dd2012-12-18 14:30:41 +00005289}
5290
5291/// \brief It annotates and advances tokens with a cursor until the comparison
5292//// between the cursor location and the source range is the same as
5293/// \arg compResult.
5294///
5295/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
5296/// Pass RangeOverlap to annotate tokens inside a range.
5297void AnnotateTokensWorker::annotateAndAdvanceTokens(CXCursor updateC,
5298 RangeComparisonResult compResult,
5299 SourceRange range) {
5300 while (MoreTokens()) {
5301 const unsigned I = NextToken();
5302 if (isFunctionMacroToken(I))
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005303 if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
5304 return;
Guy Benyei11169dd2012-12-18 14:30:41 +00005305
5306 SourceLocation TokLoc = GetTokenLoc(I);
5307 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005308 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005309 AdvanceToken();
5310 continue;
5311 }
5312 break;
5313 }
5314}
5315
5316/// \brief Special annotation handling for macro argument tokens.
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005317/// \returns true if it advanced beyond all macro tokens, false otherwise.
5318bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
Guy Benyei11169dd2012-12-18 14:30:41 +00005319 CXCursor updateC,
5320 RangeComparisonResult compResult,
5321 SourceRange range) {
5322 assert(MoreTokens());
5323 assert(isFunctionMacroToken(NextToken()) &&
5324 "Should be called only for macro arg tokens");
5325
5326 // This works differently than annotateAndAdvanceTokens; because expanded
5327 // macro arguments can have arbitrary translation-unit source order, we do not
5328 // advance the token index one by one until a token fails the range test.
5329 // We only advance once past all of the macro arg tokens if all of them
5330 // pass the range test. If one of them fails we keep the token index pointing
5331 // at the start of the macro arg tokens so that the failing token will be
5332 // annotated by a subsequent annotation try.
5333
5334 bool atLeastOneCompFail = false;
5335
5336 unsigned I = NextToken();
5337 for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
5338 SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
5339 if (TokLoc.isFileID())
5340 continue; // not macro arg token, it's parens or comma.
5341 if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
5342 if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
5343 Cursors[I] = updateC;
5344 } else
5345 atLeastOneCompFail = true;
5346 }
5347
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005348 if (atLeastOneCompFail)
5349 return false;
5350
5351 TokIdx = I; // All of the tokens were handled, advance beyond all of them.
5352 return true;
Guy Benyei11169dd2012-12-18 14:30:41 +00005353}
5354
5355enum CXChildVisitResult
5356AnnotateTokensWorker::Visit(CXCursor cursor, CXCursor parent) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005357 SourceRange cursorRange = getRawCursorExtent(cursor);
5358 if (cursorRange.isInvalid())
5359 return CXChildVisit_Recurse;
5360
5361 if (!HasContextSensitiveKeywords) {
5362 // Objective-C properties can have context-sensitive keywords.
5363 if (cursor.kind == CXCursor_ObjCPropertyDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005364 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005365 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
5366 HasContextSensitiveKeywords = Property->getPropertyAttributesAsWritten() != 0;
5367 }
5368 // Objective-C methods can have context-sensitive keywords.
5369 else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
5370 cursor.kind == CXCursor_ObjCClassMethodDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005371 if (const ObjCMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005372 = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
5373 if (Method->getObjCDeclQualifier())
5374 HasContextSensitiveKeywords = true;
5375 else {
Aaron Ballman43b68be2014-03-07 17:50:17 +00005376 for (const auto *P : Method->params()) {
5377 if (P->getObjCDeclQualifier()) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005378 HasContextSensitiveKeywords = true;
5379 break;
5380 }
5381 }
5382 }
5383 }
5384 }
5385 // C++ methods can have context-sensitive keywords.
5386 else if (cursor.kind == CXCursor_CXXMethod) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005387 if (const CXXMethodDecl *Method
Guy Benyei11169dd2012-12-18 14:30:41 +00005388 = dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
5389 if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
5390 HasContextSensitiveKeywords = true;
5391 }
5392 }
5393 // C++ classes can have context-sensitive keywords.
5394 else if (cursor.kind == CXCursor_StructDecl ||
5395 cursor.kind == CXCursor_ClassDecl ||
5396 cursor.kind == CXCursor_ClassTemplate ||
5397 cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005398 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00005399 if (D->hasAttr<FinalAttr>())
5400 HasContextSensitiveKeywords = true;
5401 }
5402 }
Argyrios Kyrtzidis990b3862013-06-04 18:24:30 +00005403
5404 // Don't override a property annotation with its getter/setter method.
5405 if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
5406 parent.kind == CXCursor_ObjCPropertyDecl)
5407 return CXChildVisit_Continue;
Guy Benyei11169dd2012-12-18 14:30:41 +00005408
5409 if (clang_isPreprocessing(cursor.kind)) {
5410 // Items in the preprocessing record are kept separate from items in
5411 // declarations, so we keep a separate token index.
5412 unsigned SavedTokIdx = TokIdx;
5413 TokIdx = PreprocessingTokIdx;
5414
5415 // Skip tokens up until we catch up to the beginning of the preprocessing
5416 // entry.
5417 while (MoreTokens()) {
5418 const unsigned I = NextToken();
5419 SourceLocation TokLoc = GetTokenLoc(I);
5420 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5421 case RangeBefore:
5422 AdvanceToken();
5423 continue;
5424 case RangeAfter:
5425 case RangeOverlap:
5426 break;
5427 }
5428 break;
5429 }
5430
5431 // Look at all of the tokens within this range.
5432 while (MoreTokens()) {
5433 const unsigned I = NextToken();
5434 SourceLocation TokLoc = GetTokenLoc(I);
5435 switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
5436 case RangeBefore:
5437 llvm_unreachable("Infeasible");
5438 case RangeAfter:
5439 break;
5440 case RangeOverlap:
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005441 // For macro expansions, just note where the beginning of the macro
5442 // expansion occurs.
5443 if (cursor.kind == CXCursor_MacroExpansion) {
5444 if (TokLoc == cursorRange.getBegin())
5445 Cursors[I] = cursor;
5446 AdvanceToken();
5447 break;
5448 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005449 // We may have already annotated macro names inside macro definitions.
5450 if (Cursors[I].kind != CXCursor_MacroExpansion)
5451 Cursors[I] = cursor;
Guy Benyei11169dd2012-12-18 14:30:41 +00005452 AdvanceToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005453 continue;
5454 }
5455 break;
5456 }
5457
5458 // Save the preprocessing token index; restore the non-preprocessing
5459 // token index.
5460 PreprocessingTokIdx = TokIdx;
5461 TokIdx = SavedTokIdx;
5462 return CXChildVisit_Recurse;
5463 }
5464
5465 if (cursorRange.isInvalid())
5466 return CXChildVisit_Continue;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005467
5468 unsigned BeforeReachingCursorIdx = NextToken();
Guy Benyei11169dd2012-12-18 14:30:41 +00005469 const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005470 const enum CXCursorKind K = clang_getCursorKind(parent);
5471 const CXCursor updateC =
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005472 (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
5473 // Attributes are annotated out-of-order, skip tokens until we reach it.
5474 clang_isAttribute(cursor.kind))
Guy Benyei11169dd2012-12-18 14:30:41 +00005475 ? clang_getNullCursor() : parent;
5476
5477 annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);
5478
5479 // Avoid having the cursor of an expression "overwrite" the annotation of the
5480 // variable declaration that it belongs to.
5481 // This can happen for C++ constructor expressions whose range generally
5482 // include the variable declaration, e.g.:
5483 // MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005484 if (clang_isExpression(cursorK) && MoreTokens()) {
Dmitri Gribenkoe8354062013-01-26 15:29:08 +00005485 const Expr *E = getCursorExpr(cursor);
Dmitri Gribenkoa1691182013-01-26 18:12:08 +00005486 if (const Decl *D = getCursorParentDecl(cursor)) {
Guy Benyei11169dd2012-12-18 14:30:41 +00005487 const unsigned I = NextToken();
5488 if (E->getLocStart().isValid() && D->getLocation().isValid() &&
5489 E->getLocStart() == D->getLocation() &&
5490 E->getLocStart() == GetTokenLoc(I)) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005491 updateCursorAnnotation(Cursors[I], updateC);
Guy Benyei11169dd2012-12-18 14:30:41 +00005492 AdvanceToken();
5493 }
5494 }
5495 }
5496
5497 // Before recursing into the children keep some state that we are going
5498 // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
5499 // extra work after the child nodes are visited.
5500 // Note that we don't call VisitChildren here to avoid traversing statements
5501 // code-recursively which can blow the stack.
5502
5503 PostChildrenInfo Info;
5504 Info.Cursor = cursor;
5505 Info.CursorRange = cursorRange;
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005506 Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005507 Info.BeforeChildrenTokenIdx = NextToken();
5508 PostChildrenInfos.push_back(Info);
5509
5510 return CXChildVisit_Recurse;
5511}
5512
5513bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
5514 if (PostChildrenInfos.empty())
5515 return false;
5516 const PostChildrenInfo &Info = PostChildrenInfos.back();
5517 if (!clang_equalCursors(Info.Cursor, cursor))
5518 return false;
5519
5520 const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
5521 const unsigned AfterChildren = NextToken();
5522 SourceRange cursorRange = Info.CursorRange;
5523
5524 // Scan the tokens that are at the end of the cursor, but are not captured
5525 // but the child cursors.
5526 annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);
5527
5528 // Scan the tokens that are at the beginning of the cursor, but are not
5529 // capture by the child cursors.
5530 for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
5531 if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
5532 break;
5533
5534 Cursors[I] = cursor;
5535 }
5536
Argyrios Kyrtzidisa2ed8132013-02-08 01:12:25 +00005537 // Attributes are annotated out-of-order, rewind TokIdx to when we first
5538 // encountered the attribute cursor.
5539 if (clang_isAttribute(cursor.kind))
5540 TokIdx = Info.BeforeReachingCursorIdx;
5541
Guy Benyei11169dd2012-12-18 14:30:41 +00005542 PostChildrenInfos.pop_back();
5543 return false;
5544}
5545
5546static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
5547 CXCursor parent,
5548 CXClientData client_data) {
5549 return static_cast<AnnotateTokensWorker*>(client_data)->Visit(cursor, parent);
5550}
5551
5552static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
5553 CXClientData client_data) {
5554 return static_cast<AnnotateTokensWorker*>(client_data)->
5555 postVisitChildren(cursor);
5556}
5557
5558namespace {
5559
5560/// \brief Uses the macro expansions in the preprocessing record to find
5561/// and mark tokens that are macro arguments. This info is used by the
5562/// AnnotateTokensWorker.
5563class MarkMacroArgTokensVisitor {
5564 SourceManager &SM;
5565 CXToken *Tokens;
5566 unsigned NumTokens;
5567 unsigned CurIdx;
5568
5569public:
5570 MarkMacroArgTokensVisitor(SourceManager &SM,
5571 CXToken *tokens, unsigned numTokens)
5572 : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) { }
5573
5574 CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
5575 if (cursor.kind != CXCursor_MacroExpansion)
5576 return CXChildVisit_Continue;
5577
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00005578 SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
Guy Benyei11169dd2012-12-18 14:30:41 +00005579 if (macroRange.getBegin() == macroRange.getEnd())
5580 return CXChildVisit_Continue; // it's not a function macro.
5581
5582 for (; CurIdx < NumTokens; ++CurIdx) {
5583 if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
5584 macroRange.getBegin()))
5585 break;
5586 }
5587
5588 if (CurIdx == NumTokens)
5589 return CXChildVisit_Break;
5590
5591 for (; CurIdx < NumTokens; ++CurIdx) {
5592 SourceLocation tokLoc = getTokenLoc(CurIdx);
5593 if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
5594 break;
5595
5596 setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
5597 }
5598
5599 if (CurIdx == NumTokens)
5600 return CXChildVisit_Break;
5601
5602 return CXChildVisit_Continue;
5603 }
5604
5605private:
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005606 CXToken &getTok(unsigned Idx) {
5607 assert(Idx < NumTokens);
5608 return Tokens[Idx];
5609 }
5610 const CXToken &getTok(unsigned Idx) const {
5611 assert(Idx < NumTokens);
5612 return Tokens[Idx];
5613 }
5614
Guy Benyei11169dd2012-12-18 14:30:41 +00005615 SourceLocation getTokenLoc(unsigned tokI) {
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005616 return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
Guy Benyei11169dd2012-12-18 14:30:41 +00005617 }
5618
5619 void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
5620 // The third field is reserved and currently not used. Use it here
5621 // to mark macro arg expanded tokens with their expanded locations.
Argyrios Kyrtzidis50126f12013-11-27 05:50:55 +00005622 getTok(tokI).int_data[3] = loc.getRawEncoding();
Guy Benyei11169dd2012-12-18 14:30:41 +00005623 }
5624};
5625
5626} // end anonymous namespace
5627
5628static CXChildVisitResult
5629MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
5630 CXClientData client_data) {
5631 return static_cast<MarkMacroArgTokensVisitor*>(client_data)->visit(cursor,
5632 parent);
5633}
5634
5635namespace {
5636 struct clang_annotateTokens_Data {
5637 CXTranslationUnit TU;
5638 ASTUnit *CXXUnit;
5639 CXToken *Tokens;
5640 unsigned NumTokens;
5641 CXCursor *Cursors;
5642 };
5643}
5644
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005645/// \brief Used by \c annotatePreprocessorTokens.
5646/// \returns true if lexing was finished, false otherwise.
5647static bool lexNext(Lexer &Lex, Token &Tok,
5648 unsigned &NextIdx, unsigned NumTokens) {
5649 if (NextIdx >= NumTokens)
5650 return true;
5651
5652 ++NextIdx;
5653 Lex.LexFromRawLexer(Tok);
5654 if (Tok.is(tok::eof))
5655 return true;
5656
5657 return false;
5658}
5659
Guy Benyei11169dd2012-12-18 14:30:41 +00005660static void annotatePreprocessorTokens(CXTranslationUnit TU,
5661 SourceRange RegionOfInterest,
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005662 CXCursor *Cursors,
5663 CXToken *Tokens,
5664 unsigned NumTokens) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005665 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005666
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005667 Preprocessor &PP = CXXUnit->getPreprocessor();
Guy Benyei11169dd2012-12-18 14:30:41 +00005668 SourceManager &SourceMgr = CXXUnit->getSourceManager();
5669 std::pair<FileID, unsigned> BeginLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005670 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
Guy Benyei11169dd2012-12-18 14:30:41 +00005671 std::pair<FileID, unsigned> EndLocInfo
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005672 = SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());
Guy Benyei11169dd2012-12-18 14:30:41 +00005673
5674 if (BeginLocInfo.first != EndLocInfo.first)
5675 return;
5676
5677 StringRef Buffer;
5678 bool Invalid = false;
5679 Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
5680 if (Buffer.empty() || Invalid)
5681 return;
5682
5683 Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
5684 CXXUnit->getASTContext().getLangOpts(),
5685 Buffer.begin(), Buffer.data() + BeginLocInfo.second,
5686 Buffer.end());
5687 Lex.SetCommentRetentionState(true);
5688
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005689 unsigned NextIdx = 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00005690 // Lex tokens in raw mode until we hit the end of the range, to avoid
5691 // entering #includes or expanding macros.
5692 while (true) {
5693 Token Tok;
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005694 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5695 break;
5696 unsigned TokIdx = NextIdx-1;
5697 assert(Tok.getLocation() ==
5698 SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));
Guy Benyei11169dd2012-12-18 14:30:41 +00005699
5700 reprocess:
5701 if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005702 // We have found a preprocessing directive. Annotate the tokens
5703 // appropriately.
Guy Benyei11169dd2012-12-18 14:30:41 +00005704 //
5705 // FIXME: Some simple tests here could identify macro definitions and
5706 // #undefs, to provide specific cursor kinds for those.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005707
5708 SourceLocation BeginLoc = Tok.getLocation();
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005709 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5710 break;
5711
5712 MacroInfo *MI = 0;
Alp Toker2d57cea2014-05-17 04:53:25 +00005713 if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005714 if (lexNext(Lex, Tok, NextIdx, NumTokens))
5715 break;
5716
5717 if (Tok.is(tok::raw_identifier)) {
Alp Toker2d57cea2014-05-17 04:53:25 +00005718 IdentifierInfo &II =
5719 PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005720 SourceLocation MappedTokLoc =
5721 CXXUnit->mapLocationToPreamble(Tok.getLocation());
5722 MI = getMacroInfo(II, MappedTokLoc, TU);
5723 }
5724 }
5725
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005726 bool finished = false;
Guy Benyei11169dd2012-12-18 14:30:41 +00005727 do {
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005728 if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
5729 finished = true;
5730 break;
5731 }
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005732 // If we are in a macro definition, check if the token was ever a
5733 // macro name and annotate it if that's the case.
5734 if (MI) {
5735 SourceLocation SaveLoc = Tok.getLocation();
5736 Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
5737 MacroDefinition *MacroDef = checkForMacroInMacroDefinition(MI,Tok,TU);
5738 Tok.setLocation(SaveLoc);
5739 if (MacroDef)
5740 Cursors[NextIdx-1] = MakeMacroExpansionCursor(MacroDef,
5741 Tok.getLocation(), TU);
5742 }
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005743 } while (!Tok.isAtStartOfLine());
5744
5745 unsigned LastIdx = finished ? NextIdx-1 : NextIdx-2;
5746 assert(TokIdx <= LastIdx);
5747 SourceLocation EndLoc =
5748 SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
5749 CXCursor Cursor =
5750 MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);
5751
5752 for (; TokIdx <= LastIdx; ++TokIdx)
Argyrios Kyrtzidis68d31ce2013-01-07 19:16:32 +00005753 updateCursorAnnotation(Cursors[TokIdx], Cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00005754
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005755 if (finished)
5756 break;
5757 goto reprocess;
Guy Benyei11169dd2012-12-18 14:30:41 +00005758 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005759 }
5760}
5761
5762// This gets run a separate thread to avoid stack blowout.
5763static void clang_annotateTokensImpl(void *UserData) {
5764 CXTranslationUnit TU = ((clang_annotateTokens_Data*)UserData)->TU;
5765 ASTUnit *CXXUnit = ((clang_annotateTokens_Data*)UserData)->CXXUnit;
5766 CXToken *Tokens = ((clang_annotateTokens_Data*)UserData)->Tokens;
5767 const unsigned NumTokens = ((clang_annotateTokens_Data*)UserData)->NumTokens;
5768 CXCursor *Cursors = ((clang_annotateTokens_Data*)UserData)->Cursors;
5769
Dmitri Gribenko183436e2013-01-26 21:49:50 +00005770 CIndexer *CXXIdx = TU->CIdx;
Guy Benyei11169dd2012-12-18 14:30:41 +00005771 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
5772 setThreadBackgroundPriority();
5773
5774 // Determine the region of interest, which contains all of the tokens.
5775 SourceRange RegionOfInterest;
5776 RegionOfInterest.setBegin(
5777 cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
5778 RegionOfInterest.setEnd(
5779 cxloc::translateSourceLocation(clang_getTokenLocation(TU,
5780 Tokens[NumTokens-1])));
5781
Guy Benyei11169dd2012-12-18 14:30:41 +00005782 // Relex the tokens within the source range to look for preprocessing
5783 // directives.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005784 annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);
Argyrios Kyrtzidis5d47a9b2013-02-13 18:33:28 +00005785
5786 // If begin location points inside a macro argument, set it to the expansion
5787 // location so we can have the full context when annotating semantically.
5788 {
5789 SourceManager &SM = CXXUnit->getSourceManager();
5790 SourceLocation Loc =
5791 SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
5792 if (Loc.isMacroID())
5793 RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
5794 }
5795
Guy Benyei11169dd2012-12-18 14:30:41 +00005796 if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
5797 // Search and mark tokens that are macro argument expansions.
5798 MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(),
5799 Tokens, NumTokens);
5800 CursorVisitor MacroArgMarker(TU,
5801 MarkMacroArgTokensVisitorDelegate, &Visitor,
5802 /*VisitPreprocessorLast=*/true,
5803 /*VisitIncludedEntities=*/false,
5804 RegionOfInterest);
5805 MacroArgMarker.visitPreprocessedEntitiesInRegion();
5806 }
5807
5808 // Annotate all of the source locations in the region of interest that map to
5809 // a specific cursor.
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00005810 AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);
Guy Benyei11169dd2012-12-18 14:30:41 +00005811
5812 // FIXME: We use a ridiculous stack size here because the data-recursion
5813 // algorithm uses a large stack frame than the non-data recursive version,
5814 // and AnnotationTokensWorker currently transforms the data-recursion
5815 // algorithm back into a traditional recursion by explicitly calling
5816 // VisitChildren(). We will need to remove this explicit recursive call.
5817 W.AnnotateTokens();
5818
5819 // If we ran into any entities that involve context-sensitive keywords,
5820 // take another pass through the tokens to mark them as such.
5821 if (W.hasContextSensitiveKeywords()) {
5822 for (unsigned I = 0; I != NumTokens; ++I) {
5823 if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
5824 continue;
5825
5826 if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
5827 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005828 if (const ObjCPropertyDecl *Property
Guy Benyei11169dd2012-12-18 14:30:41 +00005829 = dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
5830 if (Property->getPropertyAttributesAsWritten() != 0 &&
5831 llvm::StringSwitch<bool>(II->getName())
5832 .Case("readonly", true)
5833 .Case("assign", true)
5834 .Case("unsafe_unretained", true)
5835 .Case("readwrite", true)
5836 .Case("retain", true)
5837 .Case("copy", true)
5838 .Case("nonatomic", true)
5839 .Case("atomic", true)
5840 .Case("getter", true)
5841 .Case("setter", true)
5842 .Case("strong", true)
5843 .Case("weak", true)
5844 .Default(false))
5845 Tokens[I].int_data[0] = CXToken_Keyword;
5846 }
5847 continue;
5848 }
5849
5850 if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
5851 Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
5852 IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
5853 if (llvm::StringSwitch<bool>(II->getName())
5854 .Case("in", true)
5855 .Case("out", true)
5856 .Case("inout", true)
5857 .Case("oneway", true)
5858 .Case("bycopy", true)
5859 .Case("byref", true)
5860 .Default(false))
5861 Tokens[I].int_data[0] = CXToken_Keyword;
5862 continue;
5863 }
5864
5865 if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
5866 Cursors[I].kind == CXCursor_CXXOverrideAttr) {
5867 Tokens[I].int_data[0] = CXToken_Keyword;
5868 continue;
5869 }
5870 }
5871 }
5872}
5873
5874extern "C" {
5875
5876void clang_annotateTokens(CXTranslationUnit TU,
5877 CXToken *Tokens, unsigned NumTokens,
5878 CXCursor *Cursors) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00005879 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00005880 LOG_BAD_TU(TU);
5881 return;
5882 }
5883 if (NumTokens == 0 || !Tokens || !Cursors) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005884 LOG_FUNC_SECTION { *Log << "<null input>"; }
Guy Benyei11169dd2012-12-18 14:30:41 +00005885 return;
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00005886 }
5887
5888 LOG_FUNC_SECTION {
5889 *Log << TU << ' ';
5890 CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
5891 CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens-1]);
5892 *Log << clang_getRange(bloc, eloc);
5893 }
Guy Benyei11169dd2012-12-18 14:30:41 +00005894
5895 // Any token we don't specifically annotate will have a NULL cursor.
5896 CXCursor C = clang_getNullCursor();
5897 for (unsigned I = 0; I != NumTokens; ++I)
5898 Cursors[I] = C;
5899
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00005900 ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00005901 if (!CXXUnit)
5902 return;
5903
5904 ASTUnit::ConcurrencyCheck Check(*CXXUnit);
5905
5906 clang_annotateTokens_Data data = { TU, CXXUnit, Tokens, NumTokens, Cursors };
5907 llvm::CrashRecoveryContext CRC;
5908 if (!RunSafely(CRC, clang_annotateTokensImpl, &data,
5909 GetSafetyThreadStackSize() * 2)) {
5910 fprintf(stderr, "libclang: crash detected while annotating tokens\n");
5911 }
5912}
5913
5914} // end: extern "C"
5915
5916//===----------------------------------------------------------------------===//
5917// Operations for querying linkage of a cursor.
5918//===----------------------------------------------------------------------===//
5919
5920extern "C" {
5921CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
5922 if (!clang_isDeclaration(cursor.kind))
5923 return CXLinkage_Invalid;
5924
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00005925 const Decl *D = cxcursor::getCursorDecl(cursor);
5926 if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
Rafael Espindola3ae00052013-05-13 00:12:11 +00005927 switch (ND->getLinkageInternal()) {
Rafael Espindola50df3a02013-05-25 17:16:20 +00005928 case NoLinkage:
5929 case VisibleNoLinkage: return CXLinkage_NoLinkage;
Guy Benyei11169dd2012-12-18 14:30:41 +00005930 case InternalLinkage: return CXLinkage_Internal;
5931 case UniqueExternalLinkage: return CXLinkage_UniqueExternal;
5932 case ExternalLinkage: return CXLinkage_External;
5933 };
5934
5935 return CXLinkage_Invalid;
5936}
5937} // end: extern "C"
5938
5939//===----------------------------------------------------------------------===//
5940// Operations for querying language of a cursor.
5941//===----------------------------------------------------------------------===//
5942
5943static CXLanguageKind getDeclLanguage(const Decl *D) {
5944 if (!D)
5945 return CXLanguage_C;
5946
5947 switch (D->getKind()) {
5948 default:
5949 break;
5950 case Decl::ImplicitParam:
5951 case Decl::ObjCAtDefsField:
5952 case Decl::ObjCCategory:
5953 case Decl::ObjCCategoryImpl:
5954 case Decl::ObjCCompatibleAlias:
5955 case Decl::ObjCImplementation:
5956 case Decl::ObjCInterface:
5957 case Decl::ObjCIvar:
5958 case Decl::ObjCMethod:
5959 case Decl::ObjCProperty:
5960 case Decl::ObjCPropertyImpl:
5961 case Decl::ObjCProtocol:
5962 return CXLanguage_ObjC;
5963 case Decl::CXXConstructor:
5964 case Decl::CXXConversion:
5965 case Decl::CXXDestructor:
5966 case Decl::CXXMethod:
5967 case Decl::CXXRecord:
5968 case Decl::ClassTemplate:
5969 case Decl::ClassTemplatePartialSpecialization:
5970 case Decl::ClassTemplateSpecialization:
5971 case Decl::Friend:
5972 case Decl::FriendTemplate:
5973 case Decl::FunctionTemplate:
5974 case Decl::LinkageSpec:
5975 case Decl::Namespace:
5976 case Decl::NamespaceAlias:
5977 case Decl::NonTypeTemplateParm:
5978 case Decl::StaticAssert:
5979 case Decl::TemplateTemplateParm:
5980 case Decl::TemplateTypeParm:
5981 case Decl::UnresolvedUsingTypename:
5982 case Decl::UnresolvedUsingValue:
5983 case Decl::Using:
5984 case Decl::UsingDirective:
5985 case Decl::UsingShadow:
5986 return CXLanguage_CPlusPlus;
5987 }
5988
5989 return CXLanguage_C;
5990}
5991
5992extern "C" {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005993
5994static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
5995 if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
5996 return CXAvailability_Available;
Guy Benyei11169dd2012-12-18 14:30:41 +00005997
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00005998 switch (D->getAvailability()) {
5999 case AR_Available:
6000 case AR_NotYetIntroduced:
6001 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
Benjamin Kramer656363d2013-10-15 18:53:18 +00006002 return getCursorAvailabilityForDecl(
6003 cast<Decl>(EnumConst->getDeclContext()));
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006004 return CXAvailability_Available;
6005
6006 case AR_Deprecated:
6007 return CXAvailability_Deprecated;
6008
6009 case AR_Unavailable:
6010 return CXAvailability_NotAvailable;
6011 }
Benjamin Kramer656363d2013-10-15 18:53:18 +00006012
6013 llvm_unreachable("Unknown availability kind!");
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006014}
6015
Guy Benyei11169dd2012-12-18 14:30:41 +00006016enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
6017 if (clang_isDeclaration(cursor.kind))
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006018 if (const Decl *D = cxcursor::getCursorDecl(cursor))
6019 return getCursorAvailabilityForDecl(D);
Guy Benyei11169dd2012-12-18 14:30:41 +00006020
6021 return CXAvailability_Available;
6022}
6023
6024static CXVersion convertVersion(VersionTuple In) {
6025 CXVersion Out = { -1, -1, -1 };
6026 if (In.empty())
6027 return Out;
6028
6029 Out.Major = In.getMajor();
6030
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006031 Optional<unsigned> Minor = In.getMinor();
6032 if (Minor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006033 Out.Minor = *Minor;
6034 else
6035 return Out;
6036
NAKAMURA Takumic2b5d1f2013-02-21 02:32:34 +00006037 Optional<unsigned> Subminor = In.getSubminor();
6038 if (Subminor.hasValue())
Guy Benyei11169dd2012-12-18 14:30:41 +00006039 Out.Subminor = *Subminor;
6040
6041 return Out;
6042}
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006043
6044static int getCursorPlatformAvailabilityForDecl(const Decl *D,
6045 int *always_deprecated,
6046 CXString *deprecated_message,
6047 int *always_unavailable,
6048 CXString *unavailable_message,
6049 CXPlatformAvailability *availability,
6050 int availability_size) {
6051 bool HadAvailAttr = false;
6052 int N = 0;
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006053 for (auto A : D->attrs()) {
6054 if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006055 HadAvailAttr = true;
6056 if (always_deprecated)
6057 *always_deprecated = 1;
Nico Weberaacf0312014-04-24 05:16:45 +00006058 if (deprecated_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006059 clang_disposeString(*deprecated_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006060 *deprecated_message = cxstring::createDup(Deprecated->getMessage());
Nico Weberaacf0312014-04-24 05:16:45 +00006061 }
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006062 continue;
6063 }
6064
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006065 if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006066 HadAvailAttr = true;
6067 if (always_unavailable)
6068 *always_unavailable = 1;
6069 if (unavailable_message) {
Argyrios Kyrtzidisedfe07f2014-04-24 06:05:40 +00006070 clang_disposeString(*unavailable_message);
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006071 *unavailable_message = cxstring::createDup(Unavailable->getMessage());
6072 }
6073 continue;
6074 }
6075
Aaron Ballmanb97112e2014-03-08 22:19:01 +00006076 if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006077 HadAvailAttr = true;
6078 if (N < availability_size) {
6079 availability[N].Platform
6080 = cxstring::createDup(Avail->getPlatform()->getName());
6081 availability[N].Introduced = convertVersion(Avail->getIntroduced());
6082 availability[N].Deprecated = convertVersion(Avail->getDeprecated());
6083 availability[N].Obsoleted = convertVersion(Avail->getObsoleted());
6084 availability[N].Unavailable = Avail->getUnavailable();
6085 availability[N].Message = cxstring::createDup(Avail->getMessage());
6086 }
6087 ++N;
6088 }
6089 }
6090
6091 if (!HadAvailAttr)
6092 if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
6093 return getCursorPlatformAvailabilityForDecl(
6094 cast<Decl>(EnumConst->getDeclContext()),
6095 always_deprecated,
6096 deprecated_message,
6097 always_unavailable,
6098 unavailable_message,
6099 availability,
6100 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006101
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006102 return N;
6103}
6104
Guy Benyei11169dd2012-12-18 14:30:41 +00006105int clang_getCursorPlatformAvailability(CXCursor cursor,
6106 int *always_deprecated,
6107 CXString *deprecated_message,
6108 int *always_unavailable,
6109 CXString *unavailable_message,
6110 CXPlatformAvailability *availability,
6111 int availability_size) {
6112 if (always_deprecated)
6113 *always_deprecated = 0;
6114 if (deprecated_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006115 *deprecated_message = cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006116 if (always_unavailable)
6117 *always_unavailable = 0;
6118 if (unavailable_message)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006119 *unavailable_message = cxstring::createEmpty();
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006120
Guy Benyei11169dd2012-12-18 14:30:41 +00006121 if (!clang_isDeclaration(cursor.kind))
6122 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006123
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006124 const Decl *D = cxcursor::getCursorDecl(cursor);
Guy Benyei11169dd2012-12-18 14:30:41 +00006125 if (!D)
6126 return 0;
Argyrios Kyrtzidisdc2973f2013-10-15 17:00:53 +00006127
6128 return getCursorPlatformAvailabilityForDecl(D, always_deprecated,
6129 deprecated_message,
6130 always_unavailable,
6131 unavailable_message,
6132 availability,
6133 availability_size);
Guy Benyei11169dd2012-12-18 14:30:41 +00006134}
6135
6136void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
6137 clang_disposeString(availability->Platform);
6138 clang_disposeString(availability->Message);
6139}
6140
6141CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
6142 if (clang_isDeclaration(cursor.kind))
6143 return getDeclLanguage(cxcursor::getCursorDecl(cursor));
6144
6145 return CXLanguage_Invalid;
6146}
6147
6148 /// \brief If the given cursor is the "templated" declaration
6149 /// descibing a class or function template, return the class or
6150 /// function template.
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006151static const Decl *maybeGetTemplateCursor(const Decl *D) {
Guy Benyei11169dd2012-12-18 14:30:41 +00006152 if (!D)
6153 return 0;
6154
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006155 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006156 if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
6157 return FunTmpl;
6158
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006159 if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
Guy Benyei11169dd2012-12-18 14:30:41 +00006160 if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
6161 return ClassTmpl;
6162
6163 return D;
6164}
6165
6166CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
6167 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006168 if (const Decl *D = getCursorDecl(cursor)) {
6169 const DeclContext *DC = D->getDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006170 if (!DC)
6171 return clang_getNullCursor();
6172
6173 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6174 getCursorTU(cursor));
6175 }
6176 }
6177
6178 if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006179 if (const Decl *D = getCursorDecl(cursor))
Guy Benyei11169dd2012-12-18 14:30:41 +00006180 return MakeCXCursor(D, getCursorTU(cursor));
6181 }
6182
6183 return clang_getNullCursor();
6184}
6185
6186CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
6187 if (clang_isDeclaration(cursor.kind)) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006188 if (const Decl *D = getCursorDecl(cursor)) {
6189 const DeclContext *DC = D->getLexicalDeclContext();
Guy Benyei11169dd2012-12-18 14:30:41 +00006190 if (!DC)
6191 return clang_getNullCursor();
6192
6193 return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
6194 getCursorTU(cursor));
6195 }
6196 }
6197
6198 // FIXME: Note that we can't easily compute the lexical context of a
6199 // statement or expression, so we return nothing.
6200 return clang_getNullCursor();
6201}
6202
6203CXFile clang_getIncludedFile(CXCursor cursor) {
6204 if (cursor.kind != CXCursor_InclusionDirective)
6205 return 0;
6206
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006207 const InclusionDirective *ID = getCursorInclusionDirective(cursor);
Dmitri Gribenkof9304482013-01-23 15:56:07 +00006208 return const_cast<FileEntry *>(ID->getFile());
Guy Benyei11169dd2012-12-18 14:30:41 +00006209}
6210
Argyrios Kyrtzidis9adfd8a2013-04-18 22:15:49 +00006211unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
6212 if (C.kind != CXCursor_ObjCPropertyDecl)
6213 return CXObjCPropertyAttr_noattr;
6214
6215 unsigned Result = CXObjCPropertyAttr_noattr;
6216 const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
6217 ObjCPropertyDecl::PropertyAttributeKind Attr =
6218 PD->getPropertyAttributesAsWritten();
6219
6220#define SET_CXOBJCPROP_ATTR(A) \
6221 if (Attr & ObjCPropertyDecl::OBJC_PR_##A) \
6222 Result |= CXObjCPropertyAttr_##A
6223 SET_CXOBJCPROP_ATTR(readonly);
6224 SET_CXOBJCPROP_ATTR(getter);
6225 SET_CXOBJCPROP_ATTR(assign);
6226 SET_CXOBJCPROP_ATTR(readwrite);
6227 SET_CXOBJCPROP_ATTR(retain);
6228 SET_CXOBJCPROP_ATTR(copy);
6229 SET_CXOBJCPROP_ATTR(nonatomic);
6230 SET_CXOBJCPROP_ATTR(setter);
6231 SET_CXOBJCPROP_ATTR(atomic);
6232 SET_CXOBJCPROP_ATTR(weak);
6233 SET_CXOBJCPROP_ATTR(strong);
6234 SET_CXOBJCPROP_ATTR(unsafe_unretained);
6235#undef SET_CXOBJCPROP_ATTR
6236
6237 return Result;
6238}
6239
Argyrios Kyrtzidis9d9bc012013-04-18 23:29:12 +00006240unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
6241 if (!clang_isDeclaration(C.kind))
6242 return CXObjCDeclQualifier_None;
6243
6244 Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
6245 const Decl *D = getCursorDecl(C);
6246 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6247 QT = MD->getObjCDeclQualifier();
6248 else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
6249 QT = PD->getObjCDeclQualifier();
6250 if (QT == Decl::OBJC_TQ_None)
6251 return CXObjCDeclQualifier_None;
6252
6253 unsigned Result = CXObjCDeclQualifier_None;
6254 if (QT & Decl::OBJC_TQ_In) Result |= CXObjCDeclQualifier_In;
6255 if (QT & Decl::OBJC_TQ_Inout) Result |= CXObjCDeclQualifier_Inout;
6256 if (QT & Decl::OBJC_TQ_Out) Result |= CXObjCDeclQualifier_Out;
6257 if (QT & Decl::OBJC_TQ_Bycopy) Result |= CXObjCDeclQualifier_Bycopy;
6258 if (QT & Decl::OBJC_TQ_Byref) Result |= CXObjCDeclQualifier_Byref;
6259 if (QT & Decl::OBJC_TQ_Oneway) Result |= CXObjCDeclQualifier_Oneway;
6260
6261 return Result;
6262}
6263
Argyrios Kyrtzidis7b50fc52013-07-05 20:44:37 +00006264unsigned clang_Cursor_isObjCOptional(CXCursor C) {
6265 if (!clang_isDeclaration(C.kind))
6266 return 0;
6267
6268 const Decl *D = getCursorDecl(C);
6269 if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
6270 return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
6271 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6272 return MD->getImplementationControl() == ObjCMethodDecl::Optional;
6273
6274 return 0;
6275}
6276
Argyrios Kyrtzidis23814e42013-04-18 23:53:05 +00006277unsigned clang_Cursor_isVariadic(CXCursor C) {
6278 if (!clang_isDeclaration(C.kind))
6279 return 0;
6280
6281 const Decl *D = getCursorDecl(C);
6282 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
6283 return FD->isVariadic();
6284 if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
6285 return MD->isVariadic();
6286
6287 return 0;
6288}
6289
Guy Benyei11169dd2012-12-18 14:30:41 +00006290CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
6291 if (!clang_isDeclaration(C.kind))
6292 return clang_getNullRange();
6293
6294 const Decl *D = getCursorDecl(C);
6295 ASTContext &Context = getCursorContext(C);
6296 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6297 if (!RC)
6298 return clang_getNullRange();
6299
6300 return cxloc::translateSourceRange(Context, RC->getSourceRange());
6301}
6302
6303CXString clang_Cursor_getRawCommentText(CXCursor C) {
6304 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006305 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006306
6307 const Decl *D = getCursorDecl(C);
6308 ASTContext &Context = getCursorContext(C);
6309 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6310 StringRef RawText = RC ? RC->getRawText(Context.getSourceManager()) :
6311 StringRef();
6312
6313 // Don't duplicate the string because RawText points directly into source
6314 // code.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006315 return cxstring::createRef(RawText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006316}
6317
6318CXString clang_Cursor_getBriefCommentText(CXCursor C) {
6319 if (!clang_isDeclaration(C.kind))
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006320 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006321
6322 const Decl *D = getCursorDecl(C);
6323 const ASTContext &Context = getCursorContext(C);
6324 const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
6325
6326 if (RC) {
6327 StringRef BriefText = RC->getBriefText(Context);
6328
6329 // Don't duplicate the string because RawComment ensures that this memory
6330 // will not go away.
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006331 return cxstring::createRef(BriefText);
Guy Benyei11169dd2012-12-18 14:30:41 +00006332 }
6333
Dmitri Gribenkof98dfba2013-02-01 14:13:32 +00006334 return cxstring::createNull();
Guy Benyei11169dd2012-12-18 14:30:41 +00006335}
6336
Guy Benyei11169dd2012-12-18 14:30:41 +00006337CXModule clang_Cursor_getModule(CXCursor C) {
6338 if (C.kind == CXCursor_ModuleImportDecl) {
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006339 if (const ImportDecl *ImportD =
6340 dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
Guy Benyei11169dd2012-12-18 14:30:41 +00006341 return ImportD->getImportedModule();
6342 }
6343
6344 return 0;
6345}
6346
Argyrios Kyrtzidisf6d49c32014-05-14 23:14:37 +00006347CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
6348 if (isNotUsableTU(TU)) {
6349 LOG_BAD_TU(TU);
6350 return nullptr;
6351 }
6352 if (!File)
6353 return nullptr;
6354 FileEntry *FE = static_cast<FileEntry *>(File);
6355
6356 ASTUnit &Unit = *cxtu::getASTUnit(TU);
6357 HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
6358 ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);
6359
6360 if (Module *Mod = Header.getModule()) {
6361 if (Header.getRole() != ModuleMap::ExcludedHeader)
6362 return Mod;
6363 }
6364 return nullptr;
6365}
6366
Argyrios Kyrtzidis12fdb9e2013-04-26 22:47:49 +00006367CXFile clang_Module_getASTFile(CXModule CXMod) {
6368 if (!CXMod)
6369 return 0;
6370 Module *Mod = static_cast<Module*>(CXMod);
6371 return const_cast<FileEntry *>(Mod->getASTFile());
6372}
6373
Guy Benyei11169dd2012-12-18 14:30:41 +00006374CXModule clang_Module_getParent(CXModule CXMod) {
6375 if (!CXMod)
6376 return 0;
6377 Module *Mod = static_cast<Module*>(CXMod);
6378 return Mod->Parent;
6379}
6380
6381CXString clang_Module_getName(CXModule CXMod) {
6382 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006383 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006384 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006385 return cxstring::createDup(Mod->Name);
Guy Benyei11169dd2012-12-18 14:30:41 +00006386}
6387
6388CXString clang_Module_getFullName(CXModule CXMod) {
6389 if (!CXMod)
Dmitri Gribenko36a6dd02013-02-01 14:21:22 +00006390 return cxstring::createEmpty();
Guy Benyei11169dd2012-12-18 14:30:41 +00006391 Module *Mod = static_cast<Module*>(CXMod);
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006392 return cxstring::createDup(Mod->getFullModuleName());
Guy Benyei11169dd2012-12-18 14:30:41 +00006393}
6394
Argyrios Kyrtzidis884337f2014-05-15 04:44:25 +00006395int clang_Module_isSystem(CXModule CXMod) {
6396 if (!CXMod)
6397 return 0;
6398 Module *Mod = static_cast<Module*>(CXMod);
6399 return Mod->IsSystem;
6400}
6401
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006402unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
6403 CXModule CXMod) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006404 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006405 LOG_BAD_TU(TU);
6406 return 0;
6407 }
6408 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006409 return 0;
6410 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006411 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
6412 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6413 return TopHeaders.size();
Guy Benyei11169dd2012-12-18 14:30:41 +00006414}
6415
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006416CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU,
6417 CXModule CXMod, unsigned Index) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006418 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006419 LOG_BAD_TU(TU);
6420 return 0;
6421 }
6422 if (!CXMod)
Guy Benyei11169dd2012-12-18 14:30:41 +00006423 return 0;
6424 Module *Mod = static_cast<Module*>(CXMod);
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006425 FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
Guy Benyei11169dd2012-12-18 14:30:41 +00006426
Argyrios Kyrtzidis3c5305c2013-03-13 21:13:43 +00006427 ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
6428 if (Index < TopHeaders.size())
6429 return const_cast<FileEntry *>(TopHeaders[Index]);
Guy Benyei11169dd2012-12-18 14:30:41 +00006430
6431 return 0;
6432}
6433
6434} // end: extern "C"
6435
6436//===----------------------------------------------------------------------===//
6437// C++ AST instrospection.
6438//===----------------------------------------------------------------------===//
6439
6440extern "C" {
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006441unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
6442 if (!clang_isDeclaration(C.kind))
6443 return 0;
6444
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006445 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006446 const CXXMethodDecl *Method =
6447 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Dmitri Gribenko62770be2013-05-17 18:38:35 +00006448 return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
6449}
6450
Dmitri Gribenkoe570ede2014-04-07 14:59:13 +00006451unsigned clang_CXXMethod_isConst(CXCursor C) {
6452 if (!clang_isDeclaration(C.kind))
6453 return 0;
6454
6455 const Decl *D = cxcursor::getCursorDecl(C);
6456 const CXXMethodDecl *Method =
6457 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
6458 return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
6459}
6460
Guy Benyei11169dd2012-12-18 14:30:41 +00006461unsigned clang_CXXMethod_isStatic(CXCursor C) {
6462 if (!clang_isDeclaration(C.kind))
6463 return 0;
6464
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006465 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006466 const CXXMethodDecl *Method =
6467 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006468 return (Method && Method->isStatic()) ? 1 : 0;
6469}
6470
6471unsigned clang_CXXMethod_isVirtual(CXCursor C) {
6472 if (!clang_isDeclaration(C.kind))
6473 return 0;
6474
Dmitri Gribenkod15bb302013-01-23 17:25:27 +00006475 const Decl *D = cxcursor::getCursorDecl(C);
Alp Tokera2794f92014-01-22 07:29:52 +00006476 const CXXMethodDecl *Method =
6477 D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : 0;
Guy Benyei11169dd2012-12-18 14:30:41 +00006478 return (Method && Method->isVirtual()) ? 1 : 0;
6479}
6480} // end: extern "C"
6481
6482//===----------------------------------------------------------------------===//
6483// Attribute introspection.
6484//===----------------------------------------------------------------------===//
6485
6486extern "C" {
6487CXType clang_getIBOutletCollectionType(CXCursor C) {
6488 if (C.kind != CXCursor_IBOutletCollectionAttr)
6489 return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));
6490
Dmitri Gribenkoe4baea62013-01-26 18:08:08 +00006491 const IBOutletCollectionAttr *A =
Guy Benyei11169dd2012-12-18 14:30:41 +00006492 cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));
6493
6494 return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
6495}
6496} // end: extern "C"
6497
6498//===----------------------------------------------------------------------===//
6499// Inspecting memory usage.
6500//===----------------------------------------------------------------------===//
6501
6502typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;
6503
6504static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
6505 enum CXTUResourceUsageKind k,
6506 unsigned long amount) {
6507 CXTUResourceUsageEntry entry = { k, amount };
6508 entries.push_back(entry);
6509}
6510
6511extern "C" {
6512
6513const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
6514 const char *str = "";
6515 switch (kind) {
6516 case CXTUResourceUsage_AST:
6517 str = "ASTContext: expressions, declarations, and types";
6518 break;
6519 case CXTUResourceUsage_Identifiers:
6520 str = "ASTContext: identifiers";
6521 break;
6522 case CXTUResourceUsage_Selectors:
6523 str = "ASTContext: selectors";
6524 break;
6525 case CXTUResourceUsage_GlobalCompletionResults:
6526 str = "Code completion: cached global results";
6527 break;
6528 case CXTUResourceUsage_SourceManagerContentCache:
6529 str = "SourceManager: content cache allocator";
6530 break;
6531 case CXTUResourceUsage_AST_SideTables:
6532 str = "ASTContext: side tables";
6533 break;
6534 case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
6535 str = "SourceManager: malloc'ed memory buffers";
6536 break;
6537 case CXTUResourceUsage_SourceManager_Membuffer_MMap:
6538 str = "SourceManager: mmap'ed memory buffers";
6539 break;
6540 case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
6541 str = "ExternalASTSource: malloc'ed memory buffers";
6542 break;
6543 case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
6544 str = "ExternalASTSource: mmap'ed memory buffers";
6545 break;
6546 case CXTUResourceUsage_Preprocessor:
6547 str = "Preprocessor: malloc'ed memory";
6548 break;
6549 case CXTUResourceUsage_PreprocessingRecord:
6550 str = "Preprocessor: PreprocessingRecord";
6551 break;
6552 case CXTUResourceUsage_SourceManager_DataStructures:
6553 str = "SourceManager: data structures and tables";
6554 break;
6555 case CXTUResourceUsage_Preprocessor_HeaderSearch:
6556 str = "Preprocessor: header search tables";
6557 break;
6558 }
6559 return str;
6560}
6561
6562CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006563 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006564 LOG_BAD_TU(TU);
Guy Benyei11169dd2012-12-18 14:30:41 +00006565 CXTUResourceUsage usage = { (void*) 0, 0, 0 };
6566 return usage;
6567 }
6568
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006569 ASTUnit *astUnit = cxtu::getASTUnit(TU);
Ahmed Charlesb8984322014-03-07 20:03:18 +00006570 std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
Guy Benyei11169dd2012-12-18 14:30:41 +00006571 ASTContext &astContext = astUnit->getASTContext();
6572
6573 // How much memory is used by AST nodes and types?
6574 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST,
6575 (unsigned long) astContext.getASTAllocatedMemory());
6576
6577 // How much memory is used by identifiers?
6578 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Identifiers,
6579 (unsigned long) astContext.Idents.getAllocator().getTotalMemory());
6580
6581 // How much memory is used for selectors?
6582 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Selectors,
6583 (unsigned long) astContext.Selectors.getTotalMemory());
6584
6585 // How much memory is used by ASTContext's side tables?
6586 createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_AST_SideTables,
6587 (unsigned long) astContext.getSideTableAllocatedMemory());
6588
6589 // How much memory is used for caching global code completion results?
6590 unsigned long completionBytes = 0;
6591 if (GlobalCodeCompletionAllocator *completionAllocator =
6592 astUnit->getCachedCompletionAllocator().getPtr()) {
6593 completionBytes = completionAllocator->getTotalMemory();
6594 }
6595 createCXTUResourceUsageEntry(*entries,
6596 CXTUResourceUsage_GlobalCompletionResults,
6597 completionBytes);
6598
6599 // How much memory is being used by SourceManager's content cache?
6600 createCXTUResourceUsageEntry(*entries,
6601 CXTUResourceUsage_SourceManagerContentCache,
6602 (unsigned long) astContext.getSourceManager().getContentCacheSize());
6603
6604 // How much memory is being used by the MemoryBuffer's in SourceManager?
6605 const SourceManager::MemoryBufferSizes &srcBufs =
6606 astUnit->getSourceManager().getMemoryBufferSizes();
6607
6608 createCXTUResourceUsageEntry(*entries,
6609 CXTUResourceUsage_SourceManager_Membuffer_Malloc,
6610 (unsigned long) srcBufs.malloc_bytes);
6611 createCXTUResourceUsageEntry(*entries,
6612 CXTUResourceUsage_SourceManager_Membuffer_MMap,
6613 (unsigned long) srcBufs.mmap_bytes);
6614 createCXTUResourceUsageEntry(*entries,
6615 CXTUResourceUsage_SourceManager_DataStructures,
6616 (unsigned long) astContext.getSourceManager()
6617 .getDataStructureSizes());
6618
6619 // How much memory is being used by the ExternalASTSource?
6620 if (ExternalASTSource *esrc = astContext.getExternalSource()) {
6621 const ExternalASTSource::MemoryBufferSizes &sizes =
6622 esrc->getMemoryBufferSizes();
6623
6624 createCXTUResourceUsageEntry(*entries,
6625 CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
6626 (unsigned long) sizes.malloc_bytes);
6627 createCXTUResourceUsageEntry(*entries,
6628 CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
6629 (unsigned long) sizes.mmap_bytes);
6630 }
6631
6632 // How much memory is being used by the Preprocessor?
6633 Preprocessor &pp = astUnit->getPreprocessor();
6634 createCXTUResourceUsageEntry(*entries,
6635 CXTUResourceUsage_Preprocessor,
6636 pp.getTotalMemory());
6637
6638 if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
6639 createCXTUResourceUsageEntry(*entries,
6640 CXTUResourceUsage_PreprocessingRecord,
6641 pRec->getTotalMemory());
6642 }
6643
6644 createCXTUResourceUsageEntry(*entries,
6645 CXTUResourceUsage_Preprocessor_HeaderSearch,
6646 pp.getHeaderSearchInfo().getTotalMemory());
6647
6648 CXTUResourceUsage usage = { (void*) entries.get(),
6649 (unsigned) entries->size(),
6650 entries->size() ? &(*entries)[0] : 0 };
Ahmed Charles9a16beb2014-03-07 19:33:25 +00006651 entries.release();
Guy Benyei11169dd2012-12-18 14:30:41 +00006652 return usage;
6653}
6654
6655void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
6656 if (usage.data)
6657 delete (MemUsageEntries*) usage.data;
6658}
6659
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006660CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
6661 CXSourceRangeList *skipped = new CXSourceRangeList;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006662 skipped->count = 0;
6663 skipped->ranges = 0;
6664
Dmitri Gribenko852d6222014-02-11 15:02:48 +00006665 if (isNotUsableTU(TU)) {
Dmitri Gribenko256454f2014-02-11 14:34:14 +00006666 LOG_BAD_TU(TU);
6667 return skipped;
6668 }
6669
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006670 if (!file)
6671 return skipped;
6672
6673 ASTUnit *astUnit = cxtu::getASTUnit(TU);
6674 PreprocessingRecord *ppRec = astUnit->getPreprocessor().getPreprocessingRecord();
6675 if (!ppRec)
6676 return skipped;
6677
6678 ASTContext &Ctx = astUnit->getASTContext();
6679 SourceManager &sm = Ctx.getSourceManager();
6680 FileEntry *fileEntry = static_cast<FileEntry *>(file);
6681 FileID wantedFileID = sm.translateFile(fileEntry);
6682
6683 const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
6684 std::vector<SourceRange> wantedRanges;
6685 for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(), ei = SkippedRanges.end();
6686 i != ei; ++i) {
6687 if (sm.getFileID(i->getBegin()) == wantedFileID || sm.getFileID(i->getEnd()) == wantedFileID)
6688 wantedRanges.push_back(*i);
6689 }
6690
6691 skipped->count = wantedRanges.size();
6692 skipped->ranges = new CXSourceRange[skipped->count];
6693 for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
6694 skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);
6695
6696 return skipped;
6697}
6698
Argyrios Kyrtzidis0e282ef2013-12-06 18:55:45 +00006699void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
6700 if (ranges) {
6701 delete[] ranges->ranges;
6702 delete ranges;
Argyrios Kyrtzidis9ef57752013-12-05 08:19:32 +00006703 }
6704}
6705
Guy Benyei11169dd2012-12-18 14:30:41 +00006706} // end extern "C"
6707
6708void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
6709 CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
6710 for (unsigned I = 0; I != Usage.numEntries; ++I)
6711 fprintf(stderr, " %s: %lu\n",
6712 clang_getTUResourceUsageName(Usage.entries[I].kind),
6713 Usage.entries[I].amount);
6714
6715 clang_disposeCXTUResourceUsage(Usage);
6716}
6717
6718//===----------------------------------------------------------------------===//
6719// Misc. utility functions.
6720//===----------------------------------------------------------------------===//
6721
6722/// Default to using an 8 MB stack size on "safety" threads.
6723static unsigned SafetyStackThreadSize = 8 << 20;
6724
6725namespace clang {
6726
6727bool RunSafely(llvm::CrashRecoveryContext &CRC,
6728 void (*Fn)(void*), void *UserData,
6729 unsigned Size) {
6730 if (!Size)
6731 Size = GetSafetyThreadStackSize();
6732 if (Size)
6733 return CRC.RunSafelyOnThread(Fn, UserData, Size);
6734 return CRC.RunSafely(Fn, UserData);
6735}
6736
6737unsigned GetSafetyThreadStackSize() {
6738 return SafetyStackThreadSize;
6739}
6740
6741void SetSafetyThreadStackSize(unsigned Value) {
6742 SafetyStackThreadSize = Value;
6743}
6744
6745}
6746
6747void clang::setThreadBackgroundPriority() {
6748 if (getenv("LIBCLANG_BGPRIO_DISABLE"))
6749 return;
6750
6751 // FIXME: Move to llvm/Support and make it cross-platform.
6752#ifdef __APPLE__
6753 setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
6754#endif
6755}
6756
6757void cxindex::printDiagsToStderr(ASTUnit *Unit) {
6758 if (!Unit)
6759 return;
6760
6761 for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
6762 DEnd = Unit->stored_diag_end();
6763 D != DEnd; ++D) {
Ben Langmuir749323f2014-04-22 17:40:12 +00006764 CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
Guy Benyei11169dd2012-12-18 14:30:41 +00006765 CXString Msg = clang_formatDiagnostic(&Diag,
6766 clang_defaultDiagnosticDisplayOptions());
6767 fprintf(stderr, "%s\n", clang_getCString(Msg));
6768 clang_disposeString(Msg);
6769 }
6770#ifdef LLVM_ON_WIN32
6771 // On Windows, force a flush, since there may be multiple copies of
6772 // stderr and stdout in the file system, all with different buffers
6773 // but writing to the same device.
6774 fflush(stderr);
6775#endif
6776}
6777
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006778MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
6779 SourceLocation MacroDefLoc,
6780 CXTranslationUnit TU){
6781 if (MacroDefLoc.isInvalid() || !TU)
6782 return 0;
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006783 if (!II.hadMacroDefinition())
6784 return 0;
6785
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006786 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis2d77aeb2013-01-07 19:16:30 +00006787 Preprocessor &PP = Unit->getPreprocessor();
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006788 MacroDirective *MD = PP.getMacroDirectiveHistory(&II);
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006789 if (MD) {
6790 for (MacroDirective::DefInfo
6791 Def = MD->getDefinition(); Def; Def = Def.getPreviousDefinition()) {
6792 if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
6793 return Def.getMacroInfo();
6794 }
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006795 }
6796
6797 return 0;
6798}
6799
Dmitri Gribenkoba2f7462013-01-11 21:01:49 +00006800const MacroInfo *cxindex::getMacroInfo(const MacroDefinition *MacroDef,
6801 CXTranslationUnit TU) {
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006802 if (!MacroDef || !TU)
6803 return 0;
6804 const IdentifierInfo *II = MacroDef->getName();
6805 if (!II)
6806 return 0;
6807
6808 return getMacroInfo(*II, MacroDef->getLocation(), TU);
6809}
6810
6811MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6812 const Token &Tok,
6813 CXTranslationUnit TU) {
6814 if (!MI || !TU)
6815 return 0;
6816 if (Tok.isNot(tok::raw_identifier))
6817 return 0;
6818
6819 if (MI->getNumTokens() == 0)
6820 return 0;
6821 SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
6822 MI->getDefinitionEndLoc());
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006823 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006824
6825 // Check that the token is inside the definition and not its argument list.
6826 SourceManager &SM = Unit->getSourceManager();
6827 if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
6828 return 0;
6829 if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
6830 return 0;
6831
6832 Preprocessor &PP = Unit->getPreprocessor();
6833 PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
6834 if (!PPRec)
6835 return 0;
6836
Alp Toker2d57cea2014-05-17 04:53:25 +00006837 IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006838 if (!II.hadMacroDefinition())
6839 return 0;
6840
6841 // Check that the identifier is not one of the macro arguments.
6842 if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
6843 return 0;
6844
Argyrios Kyrtzidis09c9e812013-02-20 00:54:57 +00006845 MacroDirective *InnerMD = PP.getMacroDirectiveHistory(&II);
6846 if (!InnerMD)
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006847 return 0;
6848
Argyrios Kyrtzidisb6210df2013-03-26 17:17:01 +00006849 return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006850}
6851
6852MacroDefinition *cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI,
6853 SourceLocation Loc,
6854 CXTranslationUnit TU) {
6855 if (Loc.isInvalid() || !MI || !TU)
6856 return 0;
6857
6858 if (MI->getNumTokens() == 0)
6859 return 0;
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006860 ASTUnit *Unit = cxtu::getASTUnit(TU);
Argyrios Kyrtzidis579825a2013-01-07 19:16:25 +00006861 Preprocessor &PP = Unit->getPreprocessor();
6862 if (!PP.getPreprocessingRecord())
6863 return 0;
6864 Loc = Unit->getSourceManager().getSpellingLoc(Loc);
6865 Token Tok;
6866 if (PP.getRawToken(Loc, Tok))
6867 return 0;
6868
6869 return checkForMacroInMacroDefinition(MI, Tok, TU);
6870}
6871
Guy Benyei11169dd2012-12-18 14:30:41 +00006872extern "C" {
6873
6874CXString clang_getClangVersion() {
Dmitri Gribenko2f23e9c2013-02-02 02:19:29 +00006875 return cxstring::createDup(getClangFullVersion());
Guy Benyei11169dd2012-12-18 14:30:41 +00006876}
6877
6878} // end: extern "C"
6879
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006880Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
6881 if (TU) {
Dmitri Gribenkoc22ea1c2013-01-26 18:53:38 +00006882 if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006883 LogOS << '<' << Unit->getMainFileName() << '>';
Argyrios Kyrtzidis37f2ab42013-03-05 20:21:14 +00006884 if (Unit->isMainFileAST())
6885 LogOS << " (" << Unit->getASTFileName() << ')';
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006886 return *this;
6887 }
Dmitri Gribenkoea4d1c32014-02-12 19:12:37 +00006888 } else {
6889 LogOS << "<NULL TU>";
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006890 }
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006891 return *this;
6892}
6893
Argyrios Kyrtzidisba4b5f82013-03-08 02:32:26 +00006894Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
6895 *this << FE->getName();
6896 return *this;
6897}
6898
6899Logger &cxindex::Logger::operator<<(CXCursor cursor) {
6900 CXString cursorName = clang_getCursorDisplayName(cursor);
6901 *this << cursorName << "@" << clang_getCursorLocation(cursor);
6902 clang_disposeString(cursorName);
6903 return *this;
6904}
6905
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006906Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
6907 CXFile File;
6908 unsigned Line, Column;
6909 clang_getFileLocation(Loc, &File, &Line, &Column, 0);
6910 CXString FileName = clang_getFileName(File);
6911 *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
6912 clang_disposeString(FileName);
6913 return *this;
6914}
6915
6916Logger &cxindex::Logger::operator<<(CXSourceRange range) {
6917 CXSourceLocation BLoc = clang_getRangeStart(range);
6918 CXSourceLocation ELoc = clang_getRangeEnd(range);
6919
6920 CXFile BFile;
6921 unsigned BLine, BColumn;
6922 clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, 0);
6923
6924 CXFile EFile;
6925 unsigned ELine, EColumn;
6926 clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, 0);
6927
6928 CXString BFileName = clang_getFileName(BFile);
6929 if (BFile == EFile) {
6930 *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
6931 BLine, BColumn, ELine, EColumn);
6932 } else {
6933 CXString EFileName = clang_getFileName(EFile);
6934 *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName),
6935 BLine, BColumn)
6936 << llvm::format("%s:%d:%d]", clang_getCString(EFileName),
6937 ELine, EColumn);
6938 clang_disposeString(EFileName);
6939 }
6940 clang_disposeString(BFileName);
6941 return *this;
6942}
6943
6944Logger &cxindex::Logger::operator<<(CXString Str) {
6945 *this << clang_getCString(Str);
6946 return *this;
6947}
6948
6949Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
6950 LogOS << Fmt;
6951 return *this;
6952}
6953
6954cxindex::Logger::~Logger() {
6955 LogOS.flush();
6956
6957 llvm::sys::ScopedLock L(EnableMultithreadingMutex);
6958
6959 static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();
6960
Dmitri Gribenkof8579502013-01-12 19:30:44 +00006961 raw_ostream &OS = llvm::errs();
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006962 OS << "[libclang:" << Name << ':';
6963
6964 // FIXME: Portability.
Alp Toker1d257e12014-06-04 03:28:55 +00006965#ifdef __APPLE__
Argyrios Kyrtzidisea474352013-01-10 18:54:52 +00006966 mach_port_t tid = pthread_mach_thread_np(pthread_self());
6967 OS << tid << ':';
6968#endif
6969
6970 llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
6971 OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
6972 OS << Msg.str() << '\n';
6973
6974 if (Trace) {
6975 llvm::sys::PrintStackTrace(stderr);
6976 OS << "--------------------------------------------------\n";
6977 }
6978}